django rest_framework 序列化器详解
2022年7月9日大约 3 分钟约 878 字
模型数据序列化
创建一个序列化器
序列化器与django Form
类的功能非常相似,Form类是用于前后端不分离项目的表单数据格式,而序列化器是用于前后端分离项目的JSON数据格式。
序列化器基类
编辑文件 persons/serializers.py
from rest_framework import serializers
from persons.models import PersonModel, SEX_CHOICES
class PersonSerializer(serializers.Serializer):
# 定义序列化/反序列化的字段
id = serializers.IntegerField(label='ID', read_only=True)
name = serializers.CharField(max_length=10)
sex = serializers.ChoiceField(choices=SEX_CHOICES)
age = serializers.IntegerField(allow_null=True, required=False)
mail = serializers.EmailField(allow_blank=True, required=False)
phone = serializers.CharField(max_length=20, allow_blank=True, required=False)
# serializer是有直接保存到数据库的功能的,在这里写
# 根据提供的验证过后的数据,创建并返回一个新的'PersonModel'模型实例
def create(self, validated_data):
return PersonModel.objects.create(**validated_data)
# 根据提供的验证过后的数据,更新并返回一个已经存在的'PersonModel'模型实例
def update(self, instance, validated_data):
instance.name = validated_data.get('name', instance.name)
instance.sex = validated_data.get('sex', instance.sex)
instance.age = validated_data.get('age', instance.age)
instance.mail = validated_data.get('mail', instance.mail)
instance.phone = validated_data.get('phone', instance.phone)
instance.save()
return instance
create()
和update()
方法是Serializer
类必填方法,定义了在调用serializer.save()
时如何创建和更新的模型实例。
模型序列化器类
编辑文件 persons/serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
from persons.models import PersonModel
class UserSerializer(serializers.ModelSerializer):
# person在用户模型中是反向关联关系,不会默认包含,需要手动添加显式字段
persons = serializers.PrimaryKeyRelatedField(many=True, queryset=PersonModel.objects.all())
class Meta:
model = User
fields = ('id', 'username', 'persons')
class PersonSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username') # 这里也可以使用CharField(read_only=True)
# owner = UserSerializer() # 替换默认字段,可以在json中显示外键的所有数据,而不是只显示id
class Meta:
model = PersonModel
fields = ('id', 'name', 'sex', 'age', 'mail', 'phone', 'owner')
# fields = "__all__" # 这里是映射模型的所有字段
如果是外键会默认序列化成id编号,如果想要外键直接显示所有数据,需要手动写序列化器字段来覆盖默认自动生成的外键字段
提示
ModelSerializer类是直接继承Serializer类,并不神秘,额外仅仅做了:
- 一组自动确定的字段
- 默认简单的实现了create()和update()方法
超链接模型序列化器类
编辑文件 persons/serializers.py
from rest_framework import serializers
from django.contrib.auth.models import User
from persons.models import PersonModel
class PersonSerializer(serializers.HyperlinkedModelSerializer):
owner = serializers.ReadOnlyField(source='owner.username') # 这里也可以使用CharField(read_only=True)
class Meta:
model = PersonModel
fields = ('id', 'name', 'sex', 'age', 'mail', 'phone', 'owner')
class UserSerializer(serializers.HyperlinkedModelSerializer):
# person在用户模型中是反向关联关系,不会默认包含,需要手动添加显式字段
persons = serializers.HyperlinkedRelatedField(many=True, view_name='person-detail', read_only=True)
class Meta:
model = User
fields = ('id', 'username', 'persons', 'url')
HyperlinkedModelSerializer与ModelSerializer区别:
- 默认情况下不包含id字段
- 它包含了一个url字段,HyperlinkedIdentityField
- 关联关系使用HyperlinkedRelatedField,而不是PrimaryKeyRelatedField
测试序列化器
python manage.py shell
from persons.models import PersonModel
from persons.serializers import PersonSerializer
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
# 描述序列化器实例的结构和字段(representation)
serializer = PersonSerializer()
print(repr(serializer))
# 创建一条模型数据
person1 = PersonModel(name='张三', sex=1)
person1.save()
# 将模型实例进行序列化
serializer1 = PersonSerializer(person1)
serializer1.data
json_bytes = JSONRenderer().render(serializer1.data)
# 将json字节码反序列化
from six import BytesIO
stream = BytesIO(json_bytes) # 将json字节码转成一个流(stream)
data1 = JSONParser().parse(stream) # 将流解析成python数据类型
serializer1 = PersonSerializer(data=data1) # 将数据转成序列化器
serializer1.is_valid() # 验证数据合法性
serializer1.validated_data # 查看已验证的数据
serializer1.save() # 保存到数据模型(数据库)
# 序列化查询集(querysets)
serializer2 = PersonSerializer(PersonModel.objects.all(), many=True)
serializer2.data