DRF 前篇-序列化器

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值