1、序列化器继承图:
2、定义方式:定义类继承rest_framework.serializers中的Serializer或ModelSerializer
3、序列化方式:根据模型重新定义序列化字段:
- models中:
class StudentInfo(models.Model):
name = models.CharField(max_length=200)
age = models.IntegerField()
sex = models.IntegerField()
classes = models.CharField(max_length=200)
- 序列化器中:
class StudentModelSerializer(serializers.Serializer):
""" 序列化字段, 可以定义指定的几个字段 """
""" 新增常用属性:read_only、write_only、required, 分别为序列化时只做读取、写入、必填 """
name = serializers.CharField(max_length=200, read_only=True)
age = serializers.IntegerField()
sex = serializers.IntegerField()
classes = serializers.CharField(max_length=200)
- serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。
4、调用Serializer对象:
- 源码:
-
def __init__(self, instance=None, data=empty, **kwargs): self.instance = instance if data is not empty: self.initial_data = data self.partial = kwargs.pop('partial', False) self._context = kwargs.pop('context', {}) kwargs.pop('many', None) super().__init__(**kwargs)
- 调用时有两个指定参数和一个万能接受参数
- instance:接受模型类
- data:接受反序列化的数据
- **kwargs:用于context参数额外添加数据
- 参数传递:
- save源码:
-
def save(self, **kwargs): """ 此处一大堆断言判断,看不懂,删除 """ validated_data = {**self.validated_data, **kwargs} if self.instance is not None: self.instance = self.update(self.instance, validated_data) assert self.instance is not None, ( '`update()` did not return an object instance.' ) else: self.instance = self.create(validated_data) assert self.instance is not None, ( '`create()` did not return an object instance.' ) return self.instance
- 从 if 判断中得出:
- 当 instance 不传时, instance 默认为空值,调用self.create方法
- 当 instance 传入时,调用self.updata方法
- Serializer的create和update方法:
- 源码:
-
def update(self, instance, validated_data): raise NotImplementedError('`update()` must be implemented.') def create(self, validated_data): raise NotImplementedError('`create()` must be implemented.')
-
可以看出这两个方法并没有做任何的处理,所以需要在序列器中重写这两个方法实现插入与更新的操作,所以就引入了ModelSerializer类实现完善
5、ModelSerializer
- 就是对Serializer进行完善:
- 添加了对create和update方法内容的填充
- 添加了对序列化字段的自动匹配
- 序列化字段的处理源码:
-
class ModelSerializer(Serializer): """ 这里一大堆注释 """ serializer_field_mapping = { models.AutoField: IntegerField, models.BigIntegerField: IntegerField, models.BooleanField: BooleanField, models.CharField: CharField, models.CommaSeparatedIntegerField: CharField, models.DateField: DateField, models.DateTimeField: DateTimeField, models.DecimalField: DecimalField, models.DurationField: DurationField, models.EmailField: EmailField, models.Field: ModelField, models.FileField: FileField, models.FloatField: FloatField, models.ImageField: ImageField, models.IntegerField: IntegerField, models.NullBooleanField: BooleanField, models.PositiveIntegerField: IntegerField, models.PositiveSmallIntegerField: IntegerField, models.SlugField: SlugField, models.SmallIntegerField: IntegerField, models.TextField: CharField, models.TimeField: TimeField, models.URLField: URLField, models.UUIDField: UUIDField, models.GenericIPAddressField: IPAddressField, models.FilePathField: FilePathField, }
-
解释:第一条:
-
models.AutoField: IntegerField, :
-
models.AutoField:模型中字段设置的类型
-
IntegerField:序列化器中匹配的类型
-
-
-
-
使用方法:
-
class StudentModelSerializer(serializers.ModelSerializer): class Meta: # 指定数据库模型 model = StudentInfo # 指定序列化字段, __all__:全部字段 fields = '__all__'
- 字段处理:
- 指定字段:
fields = ('id', 'name', 'age')
- 排除字段:
exclude = ('age',)
- 指明只读字段:
read_only_fields = ('id', 'age')
- 添加额外参数
extra_kwargs = { 'phone': {'required': True}, 'winxin': {'required': True}, }
- 指定字段:
-
-
create方法源码:
-
def create(self, validated_data): """ 一大堆注释 """ raise_errors_on_nested_writes('create', self, validated_data) ModelClass = self.Meta.model info = model_meta.get_field_info(ModelClass) many_to_many = {} for field_name, relation_info in info.relations.items(): if relation_info.to_many and (field_name in validated_data): many_to_many[field_name] = validated_data.pop(field_name) try: """ 将数据创建到数据库中 """ instance = ModelClass._default_manager.create(**validated_data) except TypeError: tb = traceback.format_exc() msg = ( 'Got a `TypeError` when calling `%s.%s.create()`. ' 'This may be because you have a writable field on the ' 'serializer class that is not a valid argument to ' '`%s.%s.create()`. You may need to make the field ' 'read-only, or override the %s.create() method to handle ' 'this correctly.\nOriginal exception was:\n %s' % ( ModelClass.__name__, ModelClass._default_manager.name, ModelClass.__name__, ModelClass._default_manager.name, self.__class__.__name__, tb ) ) raise TypeError(msg) # Save many-to-many relationships after the instance is created. if many_to_many: for field_name, value in many_to_many.items(): field = getattr(instance, field_name) field.set(value) return instance
-
-
update方法源码:
-
def update(self, instance, validated_data): raise_errors_on_nested_writes('update', self, validated_data) info = model_meta.get_field_info(instance) m2m_fields = [] for attr, value in validated_data.items(): if attr in info.relations and info.relations[attr].to_many: m2m_fields.append((attr, value)) else: setattr(instance, attr, value) """ 保存更新的数据到数据库中 """ instance.save() for attr, value in m2m_fields: field = getattr(instance, attr) field.set(value) return instance
-