序言
序列化器是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=True或 default或者 null=True 时required 为 False 。 |
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)