当前位置: 代码迷 >> 综合 >> Serializer fields - Django REST framework
  详细解决方案

Serializer fields - Django REST framework

热度:100   发布时间:2023-09-14 11:10:47.0

序列化器字段-Django REST框架

fields.py

串行化字段

表单类中的每个字段不仅负责验证数据,而且还负责“清理”数据--将其规范化为一致的格式。

— Django文档

序列化器字段处理基本值和内部数据类型之间的转换。它们还处理验证输入值,以及从其父对象检索和设置值。


注:序列化器字段在fields.py,但按照约定,您应该使用from rest_framework import serializers并将字段称为serializers.<FieldName>.


核心论点

每个序列化器字段类构造函数至少接受这些参数。一些字段类采用附加的、特定于字段的参数,但应始终接受以下内容:

read_only

只读字段包含在API输出中,但在创建或更新操作期间不应包含在输入中。任何不正确地包含在序列化程序输入中的“只读”字段都将被忽略。

把这个设置为True以确保在序列化表示时使用该字段,但在反序列化期间创建或更新实例时不使用该字段。

默认为False

write_only

把这个设置为True以确保在更新或创建实例时可以使用该字段,但在序列化表示形式时不包括该字段。

默认为False

required

通常,如果在反序列化期间没有提供字段,则会引发错误。如果在反序列化过程中不需要此字段,则设置为false。

将此设置为False还允许在序列化实例时从输出中省略对象属性或字典键。如果键不存在,它就不会包含在输出表示中。

默认为True.

default

如果设置,这将提供默认值,如果未提供输入值,则该默认值将用于该字段。如果不设置,默认行为就是根本不填充属性。

这个default在部分更新操作期间不应用。在部分更新情况下,只有输入数据中提供的字段才会返回验证值。

可以设置为一个函数或其他可调用的函数,在这种情况下,每次使用该值时都会对其进行评估。当被调用时,它将不会收到任何参数。如果可调用的set_context方法,该方法将在以字段实例作为唯一参数获取值之前每次调用。它的工作方式与验证器.

序列化实例时,如果实例中没有对象属性或字典键,则将使用默认值。

注意,设置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='*'具有特殊意义,用于表示整个对象应该传递到字段。这对于创建嵌套表示或需要访问完整对象以确定输出表示形式的字段非常有用。

默认为该字段的名称。

验证器

应该应用于传入字段输入的验证器函数列表,这些函数可以引发验证错误,也可以简单地返回。验证器函数通常应该引发serializers.ValidationError,但是Django的内置ValidationError还支持与Django代码库或第三方Django包中定义的验证器兼容。

error_messages

错误信息的错误代码字典。

label

一个简短的文本字符串,可用作HTML表单字段或其他描述性元素中字段的名称。

help_text

可用作HTML表单字段或其他描述元素中字段的描述的文本字符串。

initial

用于预先填充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&Forms文件。


布尔字段

布尔菲尔德

布尔表示。

当使用HTML编码的表单输入时,请注意省略值将始终被视为将字段设置为False,即使它有一个default=True选项指定。这是因为HTML复选框输入通过省略值来表示未选中状态,因此REST框架将省略视为空复选框输入。

注意Django 2.1删除了blank克沃格models.BooleanField...之前Django 2.1models.BooleanField字段总是blank=True...因此Django 2.1默认serializers.BooleanField实例将在不使用requiredkwarg(即相当于required=True)而在Django的早期版本中,默认布尔菲尔德实例将使用required=False选择。如果要手动控制此行为,请显式声明布尔菲尔德类,或者使用extra_kwargs选项设置required旗子。

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

签署: BooleanField()

NullBooleanfield

也接受None作为有效值。

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

签署: NullBooleanField()


字符串字段

查菲尔德

文本表示。可选地验证文本短于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

文本表示形式,将文本验证为有效的电子邮件地址.

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

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

雷杰斯菲尔德

一个文本表示,它验证给定值与某个正则表达式匹配。

对应于django.forms.fields.RegexField.

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

强制性regex参数可以是字符串,也可以是已编译的python正则表达式对象。

使用Django‘sdjango.core.validators.RegexValidator为了验证。

斯卢格菲尔德

A 雷杰斯菲尔德,它根据模式验证输入。[a-zA-Z0-9_-]+.

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

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

乌尔菲尔德

A 雷杰斯菲尔德它根据URL匹配模式验证输入。期望表单的完全限定URLhttp://<host>/<path>.

对应于django.db.models.fields.URLField...使用Django‘sdjango.core.validators.URLValidator为了验证。

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

UUIDfield

确保输入是有效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'-UUID的128位整数表示:"123456789012312313134124512351145145114"
    • 'urn'-RFC 4122 URN代表UUID:"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-指定是否应包括PATH的所有子目录。默认值是False.
  • allow_files-指定是否应包括指定位置的文件。默认值是True...不是这个就是allow_folders一定是True.
  • allow_folders-指定是否应包括指定位置的文件夹。默认值是False...不是这个就是allow_files一定是True.

IPAddressField

确保输入的字段是有效的IPv 4或IPv 6字符串。

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

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

  • protocol限制指定协议的有效输入。接受的值为“两者”(默认)、“IPv 4”或“IPv 6”。匹配是不区分大小写的。
  • unpack_ipv4解包IPv 4映射地址,如::ffff:192.0.2.1。如果启用此选项,则该地址将解压缩到192.0.2.1。默认值被禁用。只能在协议设置为“两者”时使用。

数值字段

Integerfield

整数表示。

对应于django.db.models.fields.IntegerField, django.db.models.fields.SmallIntegerField, django.db.models.fields.PositiveIntegerFielddjango.db.models.fields.PositiveSmallIntegerField.

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

  • max_value验证所提供的数字不大于此值。
  • min_value验证所提供的数字不少于此值。

浮场

浮点表示。

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

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

  • max_value验证所提供的数字不大于此值。
  • min_value验证所提供的数字不少于此值。

十进场

以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将量化时使用的舍入模式设置为配置的精度。有效值为decimal模块舍入模式...默认为None.

示例用法

要以小数点2位的分辨率验证高达999位的数字,您可以使用:

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

为了验证任何小于10亿的数字,其分辨率为小数点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指示Pythondatetime对象应由to_representation...在这种情况下,日期时间编码将由呈现程序确定。
  • input_formats-表示可用于分析日期的输入格式的字符串列表。如果未指定,则DATETIME_INPUT_FORMATS设置,默认为['iso-8601'].
  • default_timezone-Apytz.timezone表示时区。如果未指定,则为USE_TZ设置启用,此设置默认为当前时区...如果USE_TZ被禁用,则Datetime对象将是天真的。

DateTimefield格式化字符串。

格式字符串可以是Pythonstrftime格式,它显式地指定格式或特殊字符串。'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

达特菲尔德

日期表示法。

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

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

  • format-表示输出格式的字符串。如果未指定,则默认为与DATE_FORMAT设置键,它将是'iso-8601'除非被设定。设置为格式字符串表示to_representation应该强迫返回值输出字符串。格式字符串描述如下。将此值设置为None指示Pythondate对象应由to_representation...在这种情况下,日期编码将由呈现器确定。
  • input_formats-表示可用于分析日期的输入格式的字符串列表。如果未指定,则DATE_INPUT_FORMATS设置,默认为['iso-8601'].

达特菲尔德格式字符串

格式字符串可以是Pythonstrftime格式,它显式地指定格式或特殊字符串。'iso-8601',这表明ISO 8601应该使用样式日期。(如'2013-01-29')

时间场

时间表示法。

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

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

  • format-表示输出格式的字符串。如果未指定,则默认为与TIME_FORMAT设置键,它将是'iso-8601'除非被设定。设置为格式字符串表示to_representation应该强迫返回值输出字符串。格式字符串描述如下。将此值设置为None指示Pythontime对象应由to_representation...在这种情况下,时间编码将由渲染器确定。
  • input_formats-表示可用于分析日期的输入格式的字符串列表。如果未指定,则TIME_INPUT_FORMATS设置,默认为['iso-8601'].

时间场格式字符串

格式字符串可以是Pythonstrftime格式,它显式地指定格式或特殊字符串。'iso-8601',这表明ISO 8601应该使用样式时间。(如'12:34:56.000000')

持久场

持续时间表示。对应于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验证所提供的持续时间不少于此值。

选择选择字段

选择场

可以从有限的一组选择中接受值的字段。

ModelSerializer如果对应的模型字段包括choices=…争论。

签署: ChoiceField(choices)

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

双双allow_blankallow_null上的有效选项选择场,尽管强烈建议您只使用一种而不是同时使用一种。allow_blank应优先用于文本选择,以及allow_null对于数字或其他非文本选择,应优先考虑。

多重选择场

可以接受从有限的一组选择中选择的一组零、一个或多个值的字段。只需要一个强制性的论证。to_internal_value返回set包含选定的值。

签署: MultipleChoiceField(choices)

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

同.一样选择场,都是allow_blankallow_null选项是有效的,尽管强烈建议您只使用一种,而不是同时使用一种。allow_blank应优先用于文本选择,以及allow_null对于数字或其他非文本选择,应优先考虑。


文件上传字段

解析器和文件上传。

这个FileField意象场类只适合与MultiPartParserFileUploadParser...大多数解析器,例如JSON不支持文件上传。姜戈正规文件上传处理程序用于处理上载的文件。

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除非另有规定。

意象场

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

对应于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(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)
)

这个利斯特菲尔德类还支持一种声明式样式,允许您编写可重用的列表字段类。

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

我们现在可以重用我们的自定义了。StringListField类,而不必提供child对它的争论。

迪克菲尔德

验证对象字典的字段类。钥匙在里面迪克菲尔德总是被假定为字符串值。

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

  • child-一个字段实例,用于验证字典中的值。如果不提供此参数,则映射中的值将不会被验证。
  • allow_empty-如果允许使用空字典,则指定。

例如,要创建一个验证字符串到字符串的映射的字段,您可以编写如下所示的内容:

document = DictField(child=CharField())

您还可以使用声明式样式,如利斯特菲尔德...例如:

class DocumentField(DictField):child = CharField()

HStorefield

预配置迪克菲尔德与Django的Postgres兼容HStorefield.

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

  • child-一个字段实例,用于验证字典中的值。默认子字段同时接受空字符串和空值。
  • allow_empty-如果允许使用空字典,则指定。

注意,子字段是.的一个实例查菲尔德,因为hstore扩展将值存储为字符串。

JSONfield

一个字段类,它验证传入的数据结构由有效的JSON原语组成。在它的备用二进制模式中,它将表示和验证JSON编码的二进制字符串。

签名: JSONField(binary, encoder)

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

杂域

ReadOnlyField

一个字段类,它只返回字段的值而不进行修改。

默认情况下,此字段用于ModelSerializer当包含与属性相关的字段名时,而不是模型字段。

签名: ReadOnlyField()

例如,如果has_expiredAccount模型,则下面的序列化程序将自动将其生成为ReadOnlyField:

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

隐场

字段类,它不接受基于用户输入的值,而是从默认值或可调用的值中获取值。

签名: HiddenField()

例如,要包含一个始终提供当前时间作为序列化程序验证数据的一部分的字段,可以使用以下方法:

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

这个隐场类通常只有在需要基于某些预先提供的字段值运行的验证时才需要,但不希望向最终用户公开所有这些字段。

的更多例子隐场见验证器文件。

模型场

可以绑定到任意模型字段的泛型字段。这个模型场类将序列化/反序列化任务委托给其关联的模型字段。此字段可用于为自定义模型字段创建序列化器字段,而不必创建新的自定义序列化器字段。

此字段由ModelSerializer若要对应自定义模型字段类,请执行以下操作。

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

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

序列化方法字段

这是一个只读字段。它通过调用附加到的序列化程序类上的方法来获得它的值。它可用于将任何类型的数据添加到对象的序列化表示形式中。

签名: 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 serializersclass UserSerializer(serializers.ModelSerializer):days_since_joined = serializers.SerializerMethodField()class Meta:model = Userdef 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()方法来将原始数据类型还原到其内部python表示中。此方法应引发serializers.ValidationError如果数据无效。

注意,WritableField版本2.x中存在的类不再存在。你应该子类Field和覆盖to_internal_value()如果字段支持数据输入。

实例

一个基本的自定义域

让我们看一个序列化表示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, blueclass 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 instancedef 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 retdef to_internal_value(self, data):ret = {"x_coordinate": data["x"],"y_coordinate": data["y"],}return retclass DataPointSerializer(serializers.ModelSerializer):coordinates = CoordinateField(source='*')class Meta:model = DataPointfields = ['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必须映射回适合更新目标对象的DECT。带着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 = DataPointfields = ['label', 'coordinates']

在这里,目标和源属性对之间的映射(xx_coordinate, yy_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-REST框架-gis

这个Django-REST框架-gis包为Django REST框架提供地理加载项,如GeometryField字段和GeoJSON序列化程序。

Django-REST框架-hStore

这个Django-REST框架-hStore包提供了一个HStorefield支持Django-hStoreDictionaryField模型场

  相关解决方案