drf高级二 序列化器

时间:2023-02-15 12:01:02

序言

序列化器是drf非常好用的一个功能!美酒虽好,切莫贪杯。合适的位置做合适的事情。drf非常擅长列表类,非图表类。此时,基础的视图是一个比较好的选择。

序列化器

序列化分为正序列化反序列化正序列化:models对象通过序列花器返回格式化的数据。反序列化:将前端提交的数据通过序列化,经过数据校验后,变成models对象保存到数据库。

REST 框架中的序列化程序的工作方式与 Django 和类非常相似。Form ModelForm Serializer响应输出ModelSerializer创建处理模型实例和查询集的序列化。

fields

序列化器和内部数据类型之间的转换(自定义序列化器和模型之间数据)。它们还处理验证输入值(数据验证)。

# 导入路径
from rest_framework.serializers import (
    Field,
    CharField
)

# Field 源码
class Field:
    _creation_counter = 0

    default_error_messages = {
        'required': _('This field is required.'),
        'null': _('This field may not be null.')
    }
    default_validators = []
    default_empty_html = empty
    initial = None

    def __init__(self, *, read_only=False, write_only=False,
                 required=None, default=empty, initial=empty, source=None,
                 label=None, help_text=None, style=None,
                 error_messages=None, validators=None, allow_null=False):
        self._creation_counter = Field._creation_counter
        Field._creation_counter += 1

        # If `required` is unset, then use `True` unless a default is provided.
        if required is None:
            required = default is empty and not read_only

        # Some combinations of keyword arguments do not make sense.
        assert not (read_only and write_only), NOT_READ_ONLY_WRITE_ONLY
        assert not (read_only and required), NOT_READ_ONLY_REQUIRED
        assert not (required and default is not empty), NOT_REQUIRED_DEFAULT
        assert not (read_only and self.__class__ == Field), USE_READONLYFIELD

        self.read_only = read_only
        self.write_only = write_only
        self.required = required
        self.default = default
        self.source = source
        self.initial = self.initial if (initial is empty) else initial
        self.label = label
        self.help_text = help_text
        self.style = {} if style is None else style
        self.allow_null = allow_null

        if self.default_empty_html is not empty:
            if default is not empty:
                self.default_empty_html = default

        if validators is not None:
            self.validators = list(validators)

        # These are set up by `.bind()` when the field is added to a serializer.
        self.field_name = None
        self.parent = None

        # Collect default error message from self and parent classes
        messages = {}
        for cls in reversed(self.__class__.__mro__):
            messages.update(getattr(cls, 'default_error_messages', {}))
        messages.update(error_messages or {})
        self.error_messages = messages

drf的fields基于继承Field参数控制序列化和反序列化验证

field通用参数

参数 默认值 描述
read_only False True该字段只在正序列化生效
write_only False True改字段只在反序列化生效
required None 如果在反序列化操作中不需要这个字段,将其设置为False。如果使用的是ModelSerializer 默认为True那么blank=Truedefault或者 null=TruerequiredFalse
default 如果设置了这个参数,提供的默认值会在这个字段没有提供输入值的时候使用。如果没有设置,默认不填充这个属性。
allow_null False 字段是否允许传入None。
source 遍历属性方法,choices参数时重写字段为CharField(source="get_字段名_display")注意:这种方式只适用序列化,反序列化会抛出异常。使用点表示法序列化字段时,如果任何对象在属性遍历期间不存在或为空,则可能需要提供一个默认值。
validators None 传入验证函数列表。要么返回None要么抛出异常被drf捕获
error_messages None 错误消息的错误代码字典。以后,异常处理时需要注意数据展示问题。
max_length

字符串类型字段

参数 默认 描述
max_length 最大长度
min_length 最小长度
allow_blank True 如果设置true,则空字符串应被视为有效值。如果设置false,则空字符串被视为无效,并将引发验证错误。
trim_whitespace True 如果设置为 ,则截断前和尾空格

数值类型字段

参数 默认 描述
max_value 验证提供的数字是否不大于此值
min_value 验证提供的数字是否不小于此值

Serializer

依据模型Product传送门

from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField(required=False)
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()

Serializer更适合序列化使用

# 可以直接序列化嵌套的列表
data = [
  {
    'email': 'x@qq.com',
    'content': '内容',
    'created': '2023-02-14 10:10:00'
  },
  {
    'email': 'x@qq.com',
    'content': '内容',
    'created': '2023-02-14 10:10:00'
  }
]
serializer = CommentSerializer(instance=data, many=True)
# 序列化查询集
# serializer = CommentSerializer(instance=Product.objects.all(), many=True)
serializer.data()

如果想要完成反序列化那么你需要完成create和update方法。恰好ModelSerializer完成解决。

序列化器源码,如果想要序列化多条使用参数many=True

from rest_framework.fields (
    Field
)
class BaseSerializer(Field):
    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)