rest framework Serializer fields

串行领域

在表单类中的每个字段不仅负责验证数据,同时也为“清洁” - 它以标准化格式一致。

- Django文档

串行字段手柄的原始值和内部数据类型之间的转换。他们还应对验证输入值,以及检索并从他们的父对象设置的值。


注:串行器字段中声明fields.py,但是按照惯例,你应该使用它们导入from rest_framework import serializers,并称之为领域serializers.<FieldName>


核心参数

每个串行领域类的构造函数至少需要这些参数。一些外地班采取额外的,现场的具体参数,但下面应该总是被接受:

read_only

只读字段包括在API输出,但不应该包括在过程中创建或更新操作输入。被错误地包含在串行化器输入的任何“READ_ONLY”字段将被忽略。

将其设置为True确保序列化的表示时,现场被使用,但在创建或反序列化时更新实例时,不使用。

默认为 False

write_only

将此设置为True以确保该字段可以更新或创建实例时被使用,但在序列化表示当不包括。

默认为 False

required

一般来说,如果反序列化期间未提供字段中的错误将被提高。设置为false,如果该字段不要求反序列化过程中。

设置这False还允许串行化实例时被从输出省略对象属性或字典键。如果该密钥不存在它根本不会被包含在输出表示。

默认为True

default

如果设置,这给了,如果没有输入值提供,将用于字段的默认值。如果没有设置默认的行为是不填充在所有的属性。

default过程中部分更新操作不适用。在部分更新情况下,仅在输入数据中提供的字段将有一个验证值返回。

可以被设定为一个函数或其他可调用,在这种情况下,该值将它每次使用时进行评估。在调用时,就无法获得任何参数。如果调用有一个requires_context = True属性,然后串行字段将作为参数传递。

例如:

class CurrentUserDefault:
    """
    May be applied as a `default=...` value on a serializer field.
    Returns the current user.
    """
    requires_context = True

    def __call__(self, serializer_field):
        return serializer_field.context['request'].user

当序列化的情况下,如果对象属性或字典键不存在于该实例默认将被使用。

请注意,设置一个default值意味着不需要领域。既包括defaultrequired关键字参数无效,将引发一个错误。

allow_null

一般来说,如果一个错误将提高None传递到串行场。设置此关键字的参数True是否None应被视为一个有效的值。

需要注意的是,没有一个明确的default,这个参数设置为True将意味着一个default价值null序列化的输出,但并不意味着对反序列化输入一个默认。

默认为 False

source

将被用来填充字段属性的名称。可以是只需要一个方法self参数,如URLField(source='get_absolute_url'),或者可以使用点号来横动属性,如EmailField(source='user.email')。当序列用虚线符号字段,它可能是必要的,以提供一个default值,如果任何对象不存在,或者是属性遍历期间空。

该值source='*'具有特殊的意义,是用来表明整个对象应通过传递到现场。这可以是用于创建嵌套的表示,或用于需要访问完整的对象,以确定输出表示字段是有用的。

默认为字段的名称。

validators

应当应用于输入字段的输入,并且其的验证函数的列表要么提高验证错误或简单地返回。验证功能通常应该提高serializers.ValidationError,但Django的内置ValidationError也支持在Django的定义验证兼容性代码库或第三方Django的包。

error_messages

的错误代码的字典来的错误消息。

label

可以使用的作为HTML表单字段或其它描述性元素的字段名称的短文本字符串。

help_text

可以使用的作为场的HTML表单字段或其它描述性元素的描述的文本字符串。

initial

应该用于A值预先填充HTML表单字段的值。您可以通过一个可调用它,就像你可以与任何常规的Django做Field

import datetime
from rest_framework import serializers
class ExampleSerializer(serializers.Serializer):
    day = serializers.DateField(initial=datetime.date.today)

style

可以用来控制渲染器如何呈现的字段键 - 值对的字典。

这里的两个例子是'input_type''base_template'

# Use <input type="password"> for the input.
password = serializers.CharField(
    style={'input_type': 'password'}
)

# Use a radio input instead of a select input.
color_channel = serializers.ChoiceField(
    choices=['red', 'green', 'blue'],
    style={'base_template': 'radio.html'}
)

欲了解更多详细信息,请参阅HTML和表单文档。


布尔类型

BooleanField

一个布尔值表示。

当使用HTML编码形式输入注意,省略了的值将总是作为一个字段设置为待处理False,即使它有一个default=True指定的选项。这是因为HTML复选框输入通过省略值表示未选中状态,所以REST框架对待不作为,如果它是一个空的复选框输入。

需要注意的是Django的2.1取出blank从kwarg models.BooleanField。在此之前的Django 2.1 models.BooleanField场总是blank=True。因此由于Django的2.1默认serializers.BooleanField实例将不生成requiredkwarg(即等同于required=True),而使用Django的早期版本中,缺省BooleanField情况下,将与生成required=False的选项。如果你想手动控制这种行为,显式声明BooleanField的序列化器类,或者使用 extra_kwargs选项来设置required标志。

对应django.db.models.fields.BooleanField

签名: BooleanField()

NullBooleanField

的布尔值表示,同时也接受None为有效的值。

对应django.db.models.fields.NullBooleanField

签名: NullBooleanField()


字符串字段

CharField

文本表示。可选验证文本比短max_length比和更长min_length

对应于django.db.models.fields.CharFielddjango.db.models.fields.TextField

签名: CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)

  • max_length - 验证该输入包含不超过此数目的字符。
  • min_length - 验证该输入含有不超过此数量的字符少。
  • allow_blank-如果设置为True,则空字符串应该被视为一个有效的值。如果设置为False,则空字符串被视为无效,将引发验证错误。默认为False
  • trim_whitespace-如果设置为True随后开头和结尾的空格修剪。默认为True

allow_null选项也可用于字符串字段,但是它的使用有利于鼓励allow_blank。它是有效的设置既allow_blank=Trueallow_null=True,但这样做意味着将有两种不同类型的空值允许的字符串表示,这可能会导致数据不一致和微妙的应用程序错误。

EmailField

文本表示,验证文本是一个有效的E-mail地址。

对应于 django.db.models.fields.EmailField

签名: EmailField(max_length=None, min_length=None, allow_blank=False)

RegexField

文本表示,即验证对特定的正则表达式给定的值匹配。

对应django.forms.fields.RegexField

签名: RegexField(regex, max_length=None, min_length=None, allow_blank=False)

强制性regex的参数可以是一个字符串,或编译蟒正则表达式对象。

使用Django的django.core.validators.RegexValidator进行验证。

SlugField

RegexField那验证对所述图案的输入[a-zA-Z0-9_-]+

对应django.db.models.fields.SlugField

签名: SlugField(max_length=50, min_length=None, allow_blank=False)

URLField

RegexField那验证对一个URL匹配模式的输入。预计形式的完全合格的URL http://<host>/<path>

对应django.db.models.fields.URLField。使用Django的django.core.validators.URLValidator进行验证。

签名: URLField(max_length=200, min_length=None, allow_blank=False)

UUIDField

确保输入A字段是有效的UUID字符串。该to_internal_value方法将返回一个uuid.UUID实例。在输出领域将在规范的连字符格式返回一个字符串,例如:

"de305d54-75b4-431b-adb2-eb6b9e546013"

签名: UUIDField(format='hex_verbose')

  • format
    

    :确定UUID值的表示格式

    • 'hex_verbose' - 的规范十六进制表示,包括连字符: "5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
    • 'hex' - 将UUID的紧凑十六进制表示,不包括连字符: "5ce0e9a55ffa654bcee01238041fb31a"
    • 'int' - A 128位整数的UUID的表示: "123456789012312313134124512351145145114"
    • 'urn'-所述UUID的RFC 4122 URN表示:"urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 更改format参数只影响表示的值。所有格式都被接受to_internal_value

FilePathField

某个域的选择是有限的文件名中的某个目录上的文件系统

对应django.forms.fields.FilePathField

签名: FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)

  • path - 绝对的文件系统路径的目录作为此FilePathField应该得到它的选择。
  • match - 一个正则表达式,作为一个字符串,即FilePathField将使用过滤器的文件名。
  • recursive-指定是否路径的所有子目录应包括在内。默认为False
  • allow_files-指定是否在指定位置的文件应包括在内。默认为True。这个或allow_folders必须True
  • allow_folders-指定是否在指定位置的文件夹应该包括在内。默认为False。这个或allow_files必须True

IPAddressField

确保输入A字段是有效的IPv4或IPv6字符串。

对应于django.forms.fields.IPAddressFielddjango.forms.fields.GenericIPAddressField

签名IPAddressField(protocol='both', unpack_ipv4=False, **options)

  • protocol限制有效输入到指定的协议。可接受的值是“既”(默认值),“IPv4的”或“的IPv6”。匹配不区分大小写。
  • unpack_ipv4解压IPv4映射像:: FFFF地址:192.0.2.1。如果启用该选项,该地址将解压到192.0.2.1。默认是禁用的。当协议设置为“两个”只能使用。

数字字段

IntegerField

整数表示。

对应于django.db.models.fields.IntegerFielddjango.db.models.fields.SmallIntegerFielddjango.db.models.fields.PositiveIntegerFielddjango.db.models.fields.PositiveSmallIntegerField

签名IntegerField(max_value=None, min_value=None)

  • max_value 验证所提供的数字是不大于该值。
  • min_value 验证所提供的数字是不低于该值。

FloatField

浮点表示。

对应django.db.models.fields.FloatField

签名FloatField(max_value=None, min_value=None)

  • max_value 验证所提供的数字是不大于该值。
  • min_value 验证所提供的数字是不低于该值。

DecimalField

十进制表示,通过在Python表示Decimal实例。

对应django.db.models.fields.DecimalField

签名DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)

  • max_digits允许数量的最大位数。它必须是None或的整数大于或等于decimal_places
  • decimal_places 小数数存储与数量。
  • coerce_to_string设置为True如果字符串值应为表示被退回,或者False如果Decimal对象应返回。默认为相同的值COERCE_DECIMAL_TO_STRING设置键,这将是True除覆盖。如果Decimal对象是由串行化器返回,则最终输出格式将被由渲染器来确定。请注意,设置localize将强制值True
  • max_value 验证所提供的数字是不大于该值。
  • min_value 验证所提供的数字是不低于该值。
  • localize设置为True启用基于当前区域的输入和输出的定位。这也将迫使coerce_to_stringTrue。默认为False。需要注意的是数据格式,如果你已经设置启用USE_L10N=True您的设置文件。
  • rounding套舍入模式quantising到所配置的精度时使用。有效值decimal模块舍入模式。默认为None

用法示例

为了验证人数达到999的2位小数的分辨率,你可以使用:

serializers.DecimalField(max_digits=5, decimal_places=2)

并验证人数达到什么不到十亿与10位小数决议:

serializers.DecimalField(max_digits=19, decimal_places=10)

该字段也有一个可选的参数,coerce_to_string。如果设置为True表示将作为一个字符串输出。如果设置为False表示将保留作为一个Decimal实例,并最终表示将通过渲染确定。

如果未设置,这将默认为相同的值COERCE_DECIMAL_TO_STRING设定,这是True除非另外设定。


日期和时间字段

DateTimeField字段

日期和时间表示。

对应django.db.models.fields.DateTimeField

签名: DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None, default_timezone=None)

  • format-表示输出格式的字符串。如果没有指定,这个默认为相同的值DATETIME_FORMAT设置键,这将是'iso-8601'除有。设置为一个格式字符串表示to_representation返回值应强制转换为字符串输出。格式字符串描述如下。将该值设置为None表示Python的datetime对象应该被返回to_representation。在这种情况下的日期时间的编码将被渲染器来确定。
  • input_formats-代表可被用于解析的日期输入格式的字符串列表。如果未指定,则DATETIME_INPUT_FORMATS设定将被使用,其缺省值为['iso-8601']
  • default_timezone-一个pytz.timezone代表时区。如果未指定和USE_TZ设置启用,这将默认为当前时区。如果USE_TZ被禁用,则datetime对象将是天真的。

DateTimeField 格式字符串。

格式字符串可以是Python中的strftime格式,其中明确指定格式,或特殊字符串'iso-8601',这表明,ISO 8601的风格日期时间应该被使用。(例如'2013-01-29T12:34:56.000000Z'

当的值None被用于格式datetime目的通过返回to_representation和最终输出表示将由渲染器类来确定。

auto_nowauto_now_add模型领域。

当使用ModelSerializerHyperlinkedModelSerializer,需要注意的是与任何型号的领域auto_now=Trueauto_now_add=True将使用的串行场read_only=True默认。

如果要覆盖此行为,你就需要声明DateTimeField明确的串行器。例如:

class CommentSerializer(serializers.ModelSerializer):
    created = serializers.DateTimeField()

    class Meta:
        model = Comment

的DateField

一个日期表示。

对应于 django.db.models.fields.DateField

签名: DateField(format=api_settings.DATE_FORMAT, input_formats=None)

  • format-表示输出格式的字符串。如果没有指定,这个默认为相同的值DATE_FORMAT设置键,这将是'iso-8601'除有。设置为一个格式字符串表示to_representation返回值应强制转换为字符串输出。格式字符串描述如下。将该值设置为None表示Python的date对象应该被返回to_representation。在这种情况下的时间将编码由渲染器来确定。
  • input_formats-代表可被用于解析的日期输入格式的字符串列表。如果未指定,则DATE_INPUT_FORMATS设定将被使用,其缺省值为['iso-8601']

DateField 格式字符串

格式字符串可以是Python中的strftime格式,其中明确指定格式,或特殊字符串'iso-8601',这表明ISO 8601风格的日期应该被使用。(例如'2013-01-29'

TimeField

时间表示。

对应于 django.db.models.fields.TimeField

签名: TimeField(format=api_settings.TIME_FORMAT, input_formats=None)

  • format-表示输出格式的字符串。如果没有指定,这个默认为相同的值TIME_FORMAT设置键,这将是'iso-8601'除有。设置为一个格式字符串表示to_representation返回值应强制转换为字符串输出。格式字符串描述如下。将该值设置为None表示Python的time对象应该被返回to_representation。在这种情况下,时间编码将由渲染器来确定。
  • input_formats-代表可被用于解析的日期输入格式的字符串列表。如果未指定,则TIME_INPUT_FORMATS设定将被使用,其缺省值为['iso-8601']

TimeField 格式字符串

格式字符串可以是Python中的strftime格式,其中明确指定格式,或特殊字符串'iso-8601',这表明,ISO 8601的风格倍应该被使用。(例如'12:34:56.000000'

DurationField

持续时间表示。对应于django.db.models.fields.DurationField

validated_data这些字段将包含一个datetime.timedelta实例。该表示是以下这种格式的字符串'[DD] [HH:[MM:]]ss[.uuuuuu]'

签名: DurationField(max_value=None, min_value=None)

  • max_value 验证所提供的持续时间不大于该值。
  • min_value 验证所提供的持续时间不低于该值。

选择选择字段

ChoiceField

一个字段可以接受的值了一组有限的选择。

通过用于ModelSerializer自动生成字段如果相应的模型字段包括choices=…参数。

签名: ChoiceField(choices)

  • choices-有效值的列表,或列表(key, display_name)的元组。
  • allow_blank-如果设置为True,则空字符串应该被视为一个有效的值。如果设置为False,则空字符串被视为无效,将引发验证错误。默认为False
  • html_cutoff-如果设置这将是将要由HTML显示选择的最大数量选择下拉。可用于确保具有非常大的可能选择的是自动生成的ChoiceFields不会阻止模板无法呈现。默认为None
  • html_cutoff_text - 如果设置,这将显示一个文本指示器,如果项目的最大数量在HTML已经截止选择下拉。默认为"More than {count} items…"

无论是allow_blankallow_null上有效的选项ChoiceField,但我们强烈建议您只使用一个,而不是两个。allow_blank应当优选用于文本选择,以及allow_null应该优选用于数字或其他非文本的选择。

MultipleChoiceField

一个字段可以接受的一组零个,一个或多个值,从一组有限的选择选择的。接受一个强制性的参数。to_internal_value返回一个set包含所选择的值。

签名: MultipleChoiceField(choices)

  • choices-有效值的列表,或列表(key, display_name)的元组。
  • allow_blank-如果设置为True,则空字符串应该被视为一个有效的值。如果设置为False,则空字符串被视为无效,将引发验证错误。默认为False
  • html_cutoff-如果设置这将是将要由HTML显示选择的最大数量选择下拉。可用于确保具有非常大的可能选择的是自动生成的ChoiceFields不会阻止模板无法呈现。默认为None
  • html_cutoff_text - 如果设置,这将显示一个文本指示器,如果项目的最大数量在HTML已经截止选择下拉。默认为"More than {count} items…"

正如ChoiceField,无论是allow_blankallow_null选项是有效的,虽然它是强烈建议您只使用一个,而不是两个。allow_blank应当优选用于文本选择,以及allow_null应该优选用于数字或其他非文本的选择。


文件上传域

解析器和文件上传。

FileFieldImageField类是仅适用于使用MultiPartParserFileUploadParser。大多数解析器,例如JSON不支持文件上传。Django的定期FILE_UPLOAD_HANDLERS用于处理上传的文件。

的FileField

一个文件表示。执行Django的标准的FileField验证。

对应django.forms.fields.FileField

签名: FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

  • max_length - 指定的文件名的最大长度。
  • allow_empty_file - 指定如果空文件是允许的。
  • use_url-如果设置为True则URL字符串值将用于输出表现。如果设置为False然后文件名的字符串值将被用于输出表示。默认为的值UPLOADED_FILES_USE_URL设置键,也就是True除非另外设定。

的ImageField

图像表示。验证上传的文件内容作为匹配已知的图像格式。

对应django.forms.fields.ImageField

签名: ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)

  • max_length - 指定的文件名的最大长度。
  • allow_empty_file - 指定如果空文件是允许的。
  • use_url-如果设置为True则URL字符串值将用于输出表现。如果设置为False然后文件名的字符串值将被用于输出表示。默认为的值UPLOADED_FILES_USE_URL设置键,也就是True除非另外设定。

要求要么Pillow包或PIL包。该Pillow建议包,PIL不再是积极维护。


复合材料领域

ListField

字段类,验证对象的列表。

签名ListField(child=<A_FIELD_INSTANCE>, allow_empty=True, min_length=None, max_length=None)

  • child - 应使用列表中的验证对象的字段实例。如果没有提供这个参数,那么在列表中无法通过验证的对象。
  • allow_empty - 指定如果空列表是允许的。
  • min_length - 验证该列表中包含不超过该数的元素少。
  • max_length - 验证该列表中包含不超过这个数目的元素。

例如,以验证您可以使用类似下面的整数列表:

scores = serializers.ListField(
   child=serializers.IntegerField(min_value=0, max_value=100)
)

ListField班还支持声明的风格,使您可以编写可重用列表字段类。

class StringListField(serializers.ListField):
    child = serializers.CharField()

现在,我们可以重复使用我们的自定义StringListField我们整个应用程序类,无需提供一个child说法吧。

DictField

字段类,验证对象的字典。钥匙放在DictField总是假定为字符串值。

签名DictField(child=<A_FIELD_INSTANCE>, allow_empty=True)

  • child - 应该用于在字典中验证值的字段实例。如果未指定该参数的映射值无法通过验证。
  • allow_empty - 指定如果空字典是允许的。

例如,要创建一个验证字符串为字符串的映射领域,你会写是这样的:

document = DictField(child=CharField())

您还可以使用声明的风格,与ListField。例如:

class DocumentField(DictField):
    child = CharField()

HStoreField

预配置的DictField是与Django的Postgres的兼容HStoreField

签名HStoreField(child=<A_FIELD_INSTANCE>, allow_empty=True)

  • child - 一个用于在词典验证值的字段的实例。默认的子场,可同时接收空字符串和空值。
  • allow_empty - 指定如果空字典是允许的。

请注意,子字段必须是一个实例CharField,作为hstore扩展存储值作为字符串。

JSONField

一个字段类,用于验证所述输入数据结构由有效的JSON原语。在其交替二进制模式,它将代表和验证JSON编码的二进制字符串。

签名JSONField(binary, encoder)

  • binary-如果设置为True则字段将输出和验证JSON编码的字符串,而不是原始的数据结构。默认为False
  • encoder-使用此JSON编码序列化输入对象。默认为None

其他领域

ReadOnlyField

一个字段类,简单地返回字段的值而无需修改。

此字段默认使用与ModelSerializer包括相关的属性而不是一个模型字段的字段名称时。

签名ReadOnlyField()

例如,如果has_expired是在一个属性Account模式,那么下面的串行会自动生成它作为ReadOnlyField

class AccountSerializer(serializers.ModelSerializer):
    class Meta:
        model = Account
        fields = ['id', 'account_name', 'has_expired']

HiddenField

这并不需要基于用户输入的值,而是一个领域类需要从缺省值或可调用它的价值。

签名HiddenField()

例如,包括一个领域,始终提供当前时间为串行数据验证的一部分,你会使用以下命令:

modified = serializers.HiddenField(default=timezone.now)

HiddenField,如果你有一些验证需要运行基于一些预先提供的字段值通常只需要一流的,但你不希望将所有这些领域的暴露给最终用户。

对于进一步的例子上HiddenField看到验证文件。

示范田

一个普通的字段,可连接到任意的模型字段。该ModelField级代表序列化/反序列化到其相关的模型领域的任务。此字段可用于创建自定义模型领域串行领域,而无需创建新的自定义序列领域。

此字段用于通过ModelSerializer对应于自定义模型领域类。

签名: ModelField(model_field=<Django ModelField instance>)

ModelField级一般用于内部使用,但如果需要的话可以通过您的API使用。为了正确实例化一个ModelField,它必须通过附加到一个实例化模型的字段。例如:ModelField(model_field=MyModel()._meta.get_field('custom_field'))

SerializerMethodField

这是一个只读字段。它通过调用它连接到串行化类中的方法获取其值。它可以用于任何类型的数据添加到您的对象的序列化表示形式。

签名SerializerMethodField(method_name=None)

  • method_name-在串行方法的名字被调用。如果不包含此默认为get_<field_name>

由称为串行方法method_name参数应该接受一个参数(除self),它是被序列化的对象。它应该返回任何你想被列入对象的序列化表示形式。例如:

from django.contrib.auth.models import User
from django.utils.timezone import now
from rest_framework import serializers

class UserSerializer(serializers.ModelSerializer):
    days_since_joined = serializers.SerializerMethodField()

    class Meta:
        model = User

    def get_days_since_joined(self, obj):
        return (now() - obj.date_joined).days


自定义字段

如果你想创建一个自定义字段,你需要的子类Field,然后覆盖任意一个或两个.to_representation().to_internal_value()方法。这两种方法被用于初始的数据类型,和一个原始的,序列化的数据类型之间进行转换。基本数据类型通常是任何数字,字符串,布尔,date/ time/ datetimeNone。它们也可以是任何列表或字典一样,只包含其他原始对象的对象。其他类型可能会因渲染器所使用的支持。

.to_representation()方法被称为初始数据类型转换成原始的,序列化的数据类型。

to_internal_value()方法被称为恢复原始数据类型到其内部蟒表示。此方法应该提出一个serializers.ValidationError如果数据是无效的。

例子

一个基本的自定义字段

让我们看一下序列化表示RGB颜色值的类的实例:

class Color(object):
    """
    A color represented in the RGB colorspace.
    """
    def __init__(self, red, green, blue):
        assert(red >= 0 and green >= 0 and blue >= 0)
        assert(red < 256 and green < 256 and blue < 256)
        self.red, self.green, self.blue = red, green, blue

class ColorField(serializers.Field):
    """
    Color objects are serialized into 'rgb(#, #, #)' notation.
    """
    def to_representation(self, value):
        return "rgb(%d, %d, %d)" % (value.red, value.green, value.blue)

    def to_internal_value(self, data):
        data = data.strip('rgb(').rstrip(')')
        red, green, blue = [int(col) for col in data.split(',')]
        return Color(red, green, blue)

通过默认字段值被视为映射到对象上的属性。如果您需要自定义字段的值如何被访问,并设置你需要重写.get_attribute()和/或.get_value()

作为一个例子,让我们创建可以被用来表示该对象的类名被序列化的字段:

class ClassNameField(serializers.Field):
    def get_attribute(self, instance):
        # We pass the object instance onto `to_representation`,
        # not just the field attribute.
        return instance

    def to_representation(self, value):
        """
        Serialize the value's class name.
        """
        return value.__class__.__name__

提高验证错误

我们ColorField上面目前类不执行任何数据验证。为了表示无效数据,我们应该提出一个serializers.ValidationError,就像这样:

def to_internal_value(self, data):
    if not isinstance(data, str):
        msg = 'Incorrect type. Expected a string, but got %s'
        raise ValidationError(msg % type(data).__name__)

    if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
        raise ValidationError('Incorrect format. Expected `rgb(#,#,#)`.')

    data = data.strip('rgb(').rstrip(')')
    red, green, blue = [int(col) for col in data.split(',')]

    if any([col > 255 or col < 0 for col in (red, green, blue)]):
        raise ValidationError('Value out of range. Must be between 0 and 255.')

    return Color(red, green, blue)

.fail()方法是提高的快捷方式ValidationError的是采用从一个消息字符串error_messages的词典。例如:

default_error_messages = {
    'incorrect_type': 'Incorrect type. Expected a string, but got {input_type}',
    'incorrect_format': 'Incorrect format. Expected `rgb(#,#,#)`.',
    'out_of_range': 'Value out of range. Must be between 0 and 255.'
}

def to_internal_value(self, data):
    if not isinstance(data, str):
        self.fail('incorrect_type', input_type=type(data).__name__)

    if not re.match(r'^rgb\([0-9]+,[0-9]+,[0-9]+\)$', data):
        self.fail('incorrect_format')

    data = data.strip('rgb(').rstrip(')')
    red, green, blue = [int(col) for col in data.split(',')]

    if any([col > 255 or col < 0 for col in (red, green, blue)]):
        self.fail('out_of_range')

    return Color(red, green, blue)

这种风格让你的错误信息更清洁,从你的代码更分开,应该是首选。

运用 source='*'

在这里,我们将采取的一个例子 DataPoint与模型x_coordinatey_coordinate属性。

class DataPoint(models.Model):
    label = models.CharField(max_length=50)
    x_coordinate = models.SmallIntegerField()
    y_coordinate = models.SmallIntegerField()

使用自定义字段,source='*'我们可以提供的坐标对的嵌套表示:

class CoordinateField(serializers.Field):

    def to_representation(self, value):
        ret = {
            "x": value.x_coordinate,
            "y": value.y_coordinate
        }
        return ret

    def to_internal_value(self, data):
        ret = {
            "x_coordinate": data["x"],
            "y_coordinate": data["y"],
        }
        return ret


class DataPointSerializer(serializers.ModelSerializer):
    coordinates = CoordinateField(source='*')

    class Meta:
        model = DataPoint
        fields = ['label', 'coordinates']

注意,这个例子不处理验证。部分由于这个原因,在实际项目中,坐标可以进行嵌套使用嵌套串行得到更好的处理source='*',有两个IntegerField实例,每个都有自己的source 指向相关领域。

从示例的要点,不过,主要有:

  • to_representation被传递的整个DataPoint对象,并且必须从映射到所期望的输出。

    >>> instance = DataPoint(label='Example', x_coordinate=1, y_coordinate=2)
    >>> out_serializer = DataPointSerializer(instance)
    >>> out_serializer.data
    ReturnDict([('label', 'Example'), ('coordinates', {'x': 1, 'y': 2})])
    
    
  • 除非我们的领域是只读的,to_internal_value必须映射回适合更新我们的目标对象的字典。随着source='*',从返回 to_internal_value将更新根验证的数据字典,而不是一个单一的关键。

    >>> data = {
    ...     "label": "Second Example",
    ...     "coordinates": {
    ...         "x": 3,
    ...         "y": 4,
    ...     }
    ... }
    >>> in_serializer = DataPointSerializer(data=data)
    >>> in_serializer.is_valid()
    True
    >>> in_serializer.validated_data
    OrderedDict([('label', 'Second Example'),
                 ('y_coordinate', 4),
                 ('x_coordinate', 3)])
    
    

为了完整起见让做同样的事情,但与嵌套的串行方法上面建议:

class NestedCoordinateSerializer(serializers.Serializer):
    x = serializers.IntegerField(source='x_coordinate')
    y = serializers.IntegerField(source='y_coordinate')


class DataPointSerializer(serializers.ModelSerializer):
    coordinates = NestedCoordinateSerializer(source='*')

    class Meta:
        model = DataPoint
        fields = ['label', 'coordinates']

这里,目标和源属性对之间的映射(xx_coordinateyy_coordinate)在被处理IntegerField 声明。这是我们NestedCoordinateSerializer认为需要source='*'

我们的新DataPointSerializer展品相同的行为自定义字段的方法。

连载:

>>> out_serializer = DataPointSerializer(instance)
>>> out_serializer.data
ReturnDict([('label', 'testing'),
            ('coordinates', OrderedDict([('x', 1), ('y', 2)]))])

反序列化:

>>> in_serializer = DataPointSerializer(data=data)
>>> in_serializer.is_valid()
True
>>> in_serializer.validated_data
OrderedDict([('label', 'still testing'),
             ('x_coordinate', 3),
             ('y_coordinate', 4)])

但是,我们也得到了内置的验证免费:

>>> invalid_data = {
...     "label": "still testing",
...     "coordinates": {
...         "x": 'a',
...         "y": 'b',
...     }
... }
>>> invalid_serializer = DataPointSerializer(data=invalid_data)
>>> invalid_serializer.is_valid()
False
>>> invalid_serializer.errors
ReturnDict([('coordinates',
             {'x': ['A valid integer is required.'],
              'y': ['A valid integer is required.']})])

为此,嵌套的串行方法是先行先试。当嵌套串行变得不可行或过于复杂,你会使用自定义字段的方法。

第三方软件包

下面的第三方软件包也可提供。

DRF复合场

DRF-化合物字段包提供“化合物”串行器领域,如简单的值的列表,其可以由其它字段,而不是与该串行器进行说明many=True的选项。还提供了用于输入的字典和值可以是特定类型或该类型的项目的列表的字段。

DRF额外的字段

DRF-额外字段软件包提供REST框架额外的串行领域,包括Base64ImageFieldPointField类。

djangorestframework递归

所述djangorestframework递归包提供了一个RecursiveField用于序列化和反序列化递归结构

Django的休息框架,地理信息系统

django的静止框架-GIS包提供地理插件为像一个Django其余框架 GeometryField字段和GeoJSON的序列化器。

Django的休息框架,hstore

django的静止框架-hstore包提供了一种HStoreField支持的django-hstore DictionaryField模型字段。

posted @ 2020-03-12 15:17  pythonliuwei  阅读(552)  评论(0编辑  收藏  举报