Form類中的每個字段不僅負(fù)責(zé)驗證數(shù)據(jù),還負(fù)責(zé)“清理”數(shù)據(jù)-將其標(biāo)準(zhǔn)化為一致的格式?!?nbsp;Django文檔
序列化器字段處理原始值和內(nèi)部數(shù)據(jù)類型之間的轉(zhuǎn)換。它們還處理驗證輸入值,以及從其父對象檢索和設(shè)置值。
注意 序列化器字段是在fields.py中聲明的, 但是按照慣例你應(yīng)該使用 from rest_framework import serializers導(dǎo)入它們并將字段稱為serializers.<FieldName>。
每個序列化程序字段類構(gòu)造函數(shù)都至少接受這些參數(shù)。某些Field類采用其他特定于字段的參數(shù),但應(yīng)始終接受以下內(nèi)容:
只讀字段包含在API輸出中,但在創(chuàng)建或更新操作期間不應(yīng)包含在輸入中。錯誤地包含在串行器輸入中的所有read_only字段都將被忽略。
進(jìn)行設(shè)置True以確保序列化表示形式時使用該字段,而在反序列化期間創(chuàng)建或更新實例時不使用該字段。
默認(rèn)為False
進(jìn)行設(shè)置True以確保在更新或創(chuàng)建實例時可以使用該字段,但在序列化表示形式時不包括該字段。
默認(rèn)為False
如果反序列化期間未提供字段,通常會引發(fā)錯誤。如果反序列化過程中不需要此字段,則設(shè)置為false。
將此設(shè)置為False還可以在序列化實例時從輸出中省略對象屬性或字典鍵。如果不存在該密鑰,則它將不會直接包含在輸出表示中。
默認(rèn)為True。
如果None傳遞給序列化器字段,通常會引發(fā)錯誤。將此關(guān)鍵字參數(shù)設(shè)置為Trueif None應(yīng)該被視為有效值。
默認(rèn)為False
如果設(shè)置,則給出默認(rèn)值,如果沒有提供輸入值,該默認(rèn)值將用于該字段。如果未設(shè)置,則默認(rèn)行為是根本不填充該屬性。
該default過程中部分更新操作不適用。在部分更新的情況下,僅傳入數(shù)據(jù)中提供的字段將返回經(jīng)過驗證的值。
可以設(shè)置為一個函數(shù)或其他可調(diào)用的,在這種情況下,每次使用該值時都會對其求值。調(diào)用時,它將不接收任何參數(shù)。如果callable具有set_context方法,則每次在將字段實例作為唯一參數(shù)獲取值之前都會被調(diào)用。這與驗證器的工作方式相同。
請注意,設(shè)置default值意味著該字段不是必需的。同時包含default和required關(guān)鍵字參數(shù)都是無效的,并且會引發(fā)錯誤。
將用于填充字段的屬性的名稱??梢允莾H接受self參數(shù)的方法,例如URLField(source='get_absolute_url'),也可以使用點分符號遍歷屬性,例如EmailField(source='user.email')。
該值source='*'具有特殊含義,用于指示應(yīng)將整個對象傳遞給該字段。這對于創(chuàng)建嵌套表示或?qū)τ谛枰L問完整對象才能確定輸出表示的字段很有用。
默認(rèn)為字段名稱。
驗證器功能列表,應(yīng)將其應(yīng)用于輸入字段輸入,并引發(fā)驗證錯誤或簡單地返回。驗證器函數(shù)通常應(yīng)該提高serializers.ValidationError,但是ValidationError還支持Django的內(nèi)置函數(shù),以便與Django代碼庫或第三方Django軟件包中定義的驗證器兼容。
錯誤代碼到錯誤消息的字典。
一個簡短的文本字符串,可用作HTML表單字段或其他描述性元素中的字段名稱。
可用作在HTML表單字段或其他描述性元素中對該字段進(jìn)行描述的文本字符串。
該值應(yīng)用于預(yù)先填充HTML表單字段的值。您可以將callable傳遞給它,就像處理任何常規(guī)Django一樣Field:
import datetime
from rest_framework import serializers
class ExampleSerializer(serializers.Serializer):
day = serializers.DateField(initial=datetime.date.today)
鍵值對字典,可用于控制渲染器應(yīng)如何渲染字段。
這里的兩個例子是'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編碼的表單輸入時,請注意,即使省略了值,也將始終將其設(shè)置為False,即使該字段default=True指定了選項。這是因為HTML復(fù)選框輸入通過忽略該值來表示未選中狀態(tài),因此REST框架將忽略視為其為空復(fù)選框輸入。
對應(yīng)于django.db.models.fields.BooleanField.
簽名: BooleanField()
表示布爾值,也接受None為有效值。
對應(yīng)于django.db.models.fields.NullBooleanField.
簽名: NullBooleanField()
表示文本。(可選)驗證文本是否短于max_length和長于min_length。
對應(yīng)于django.db.models.fields.CharField或django.db.models.fields.TextField.
簽名: CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
該allow_null選項也可用于字符串字段,盡管不建議使用allow_blank。設(shè)置allow_blank=True和allow_null=True都是有效的,但是這樣做意味著對于字符串表示而言,將存在兩種不同類型的空值,這可能導(dǎo)致數(shù)據(jù)不一致和細(xì)微的應(yīng)用程序錯誤。
表示文本形式,將文本驗證為有效的電子郵件地址。
對應(yīng)于django.db.models.fields.EmailField
簽名: EmailField(max_length=None, min_length=None, allow_blank=False)
表示文本形式,用于驗證給定值是否與某個正則表達(dá)式匹配。
對應(yīng)于django.forms.fields.RegexField.
簽名: RegexField(regex, max_length=None, min_length=None, allow_blank=False)
強(qiáng)制regex參數(shù)可以是字符串,也可以是已編譯的python正則表達(dá)式對象。
使用Django的django.core.validators.RegexValidator進(jìn)行驗證。
一個驗證輸入滿足表達(dá)式[a-zA-Z0-9_-]+的RegexField字段。
對應(yīng)于django.db.models.fields.SlugField.
簽名: SlugField(max_length=50, min_length=None, allow_blank=False)
一個驗證輸入滿足URL格式的RegexField字段。要求使用以下格式的完全限定網(wǎng)址http://<host>/<path>.
對應(yīng)于 django.db.models.fields.URLField。 使用Django的 django.core.validators.URLValidator進(jìn)行驗證。
簽名: URLField(max_length=200, min_length=None, allow_blank=False)
確保輸入為有效UUID字符串的字段。該to_internal_value方法將返回一個uuid.UUID實例。在輸出時,該字段將返回標(biāo)準(zhǔn)連字符格式的字符串,例如:
"de305d54-75b4-431b-adb2-eb6b9e546013"
簽名: UUIDField(format='hex_verbose')
一個字段,其選擇僅限于文件系統(tǒng)上某個目錄中的文件名
對應(yīng)于 django.forms.fields.FilePathField.
簽名: FilePathField(path, match=None, recursive=False, allow_files=True, allow_folders=False, required=None, **kwargs)
確保輸入為有效IPv4或IPv6字符串的字段。
對應(yīng)于 django.forms.fields.IPAddressField 和 django.forms.fields.GenericIPAddressField.
簽名:: IPAddressField(protocol='both', unpack_ipv4=False, **options)
表示整數(shù)
對應(yīng)于 django.db.models.fields.IntegerField, django.db.models.fields.SmallIntegerField, django.db.models.fields.PositiveIntegerField 和 django.db.models.fields.PositiveSmallIntegerField。
簽名: IntegerField(max_value=None, min_value=None)
表示浮點
對應(yīng)于 django.db.models.fields.FloatField.
Signature: FloatField(max_value=None, min_value=None)
表示十進(jìn)制形式,在Python中由Decimal實例表示。
對應(yīng)于 django.db.models.fields.DecimalField。
簽名: DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None)
要驗證最大為999且分辨率為2位小數(shù)的數(shù)字,請使用:
serializers.DecimalField(max_digits=5, decimal_places=2)
并使用十進(jìn)制小數(shù)位數(shù)來驗證小于十億的數(shù)字:
serializers.DecimalField(max_digits=19, decimal_places=10)
該字段還帶有一個可選參數(shù)coerce_to_string。如果設(shè)置為True表示將作為字符串輸出。如果設(shè)置為False,表示將作為Decimal實例保留,最終表示將由渲染器確定。
如果未設(shè)置,則默認(rèn)為與COERCE_DECIMAL_TO_STRING設(shè)置相同的值,True除非另行設(shè)置。
此處原與文無關(guān),2019.12.14日q1mi翻譯于北京。
表示日期和時間。
對應(yīng)于 django.db.models.fields.DateTimeField.
簽名: DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
格式字符串可以是顯式指定格式的Python strftime formats,也可以是特殊字符串'iso-8601',它指示應(yīng)使用ISO 8601樣式的日期時間。(例如'2013-01-29T12:34:56.000000Z')
當(dāng)將值None用于格式時,datetime對象將由to_representation返回,并且最終輸出表示形式將由renderer類確定。
使用ModelSerializer或HyperlinkedModelSerializer,請注意,默認(rèn)情況下帶有auto_now=True或任何模型字段auto_now_add=True都將使用read_only=True的序列化器字段。
如果要覆蓋此行為,則需要DateTimeField在序列化程序上顯式聲明。例如:
class CommentSerializer(serializers.ModelSerializer):
created = serializers.DateTimeField()
class Meta:
model = Comment
表示日期
對應(yīng)于 django.db.models.fields.DateField
簽名: DateField(format=api_settings.DATE_FORMAT, input_formats=None)
格式字符串可以是顯式指定格式的Python strftime formats,也可以是特殊字符串'iso-8601',它指示應(yīng)使用ISO 8601樣式時間。(例如'2013-01-29')
表示時間
對應(yīng)于 django.db.models.fields.TimeField
簽名: TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
格式字符串可以是顯式指定格式的Python strftime 格式,也可以是特殊字符串'iso-8601',它指示應(yīng)使用ISO 8601樣式時間。(例如'12:34:56.000000')
表示時間間隔 對應(yīng)于 django.db.models.fields.DurationField
在這些字段的validated_data將包含一個datetime.timedelta實例。該表示形式是遵循此格式的字符串'[DD] [HH:[MM:]]ss[.uuuuuu]'。
注意: 此字段僅適用于Django版本> = 1.8。
簽名: DurationField()
可以接受有限選擇集中的值的字段。
ModelSerializer如果相應(yīng)的模型字段包含choices=…參數(shù),則用于自動生成字段。
簽名: ChoiceField(choices)
無論是allow_blank與allow_null上有效的選項ChoiceField,但我們強(qiáng)烈建議您只使用一個,而不是兩個。allow_blank應(yīng)該首選用于文本選擇,并且allow_null應(yīng)該首選用于數(shù)字或其他非文本選擇。
一個可以接受一組零個,一個或多個值的字段,這些值是從一組有限的選擇中選擇的。接受一個強(qiáng)制性參數(shù)。to_internal_value返回set包含所選值的。
簽名: MultipleChoiceField(choices)
與ChoiceField一樣,allow_blank和allow_null選項都有效,盡管強(qiáng)烈建議您僅使用一個,而不要同時使用。allow_blank應(yīng)該首選用于文本選擇,并且allow_null應(yīng)該首選用于數(shù)字或其他非文本選擇。
FileField 和 ImageField類是僅適用于使用MultiPartParser或FileUploadParser的。大多數(shù)解析器(例如JSON)不支持文件上傳。Django的常規(guī)FILE_UPLOAD_HANDLERS用于處理上傳的文件。
表示文件。執(zhí)行Django的標(biāo)準(zhǔn)FileField驗證。
對應(yīng)于 django.forms.fields.FileField.
簽名: FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
表示圖片。 驗證上傳的文件內(nèi)容是否與已知圖像格式匹配。
對應(yīng)于 django.forms.fields.ImageField.
簽名: ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
需要安裝Pillow包或PIL包。推薦使用Pillow包,因為PIL包已經(jīng)不積極維護(hù)。
驗證對象列表的字段類。
簽名: ListField(child, min_length=None, max_length=None)
例如,要驗證整數(shù)列表,可以使用如下所示的內(nèi)容:
scores = serializers.ListField(
child=serializers.IntegerField(min_value=0, max_value=100)
)
ListField類還支持聲明式樣式,該樣式允許你編寫可重用的列表字段類。
class StringListField(serializers.ListField):
child = serializers.CharField()
現(xiàn)在,我們可以在整個應(yīng)用程序中重用自定義的StringListField類,而不必為其提供child參數(shù)。
一個驗證對象字典的字段類。 DictField 中的key都總是假定為字符串值。
簽名: DictField(child)
例如,要創(chuàng)建一個驗證字符串到字符串映射的字段,你可以編寫如下代碼:
document = DictField(child=CharField())
你也可以像使用一樣使用聲明式樣式ListField。例如:
class DocumentField(DictField):
child = CharField()
一個字段類,用于驗證傳入的數(shù)據(jù)結(jié)構(gòu)是否包含有效的JSON原語。在其備用二進(jìn)制模式下,它將表示并驗證JSON編碼的二進(jìn)制字符串。
簽名: JSONField(binary)
一個字段類,僅返回該字段的值而無需修改。
ModelSerializer當(dāng)包含與屬性而不是模型字段相關(guān)的字段名稱時,默認(rèn)情況下使用此字段。
簽名: ReadOnlyField()
例如,如果has_expired是Account模型的屬性,則以下序列化器將自動將其生成為ReadOnlyField:
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ('id', 'account_name', 'has_expired')
一個字段類,它不基于用戶輸入獲取值,而是從默認(rèn)值或可調(diào)用對象獲取其值。
簽名: HiddenField()
例如,要包括一個始終提供當(dāng)前時間的字段作為序列化程序驗證數(shù)據(jù)的一部分,則可以使用以下內(nèi)容:
modified = serializers.HiddenField(default=timezone.now)
HiddenField通常只有在你需要基于某些預(yù)先提供的字段值來運行某些驗證,而又不想將所有這些字段公開給最終用戶時,才需要使用該類。
有關(guān) HiddenField 的更多示例,請參照validators 文檔。
可以綁定到任意模型字段的通用字段。 ModelField類將序列化/反序列化任務(wù)委托給與其關(guān)聯(lián)的model字段。 此字段可用于為自定義模型字段創(chuàng)建序列化程序字段,而不必創(chuàng)建新的自定義序列化程序字段。
該字段用于ModelSerializer對應(yīng)于自定義模型字段類。
簽名: ModelField(model_field=<Django ModelField instance>)
ModelField一般用于內(nèi)部使用,但如果需要的話可以通過你的API使用。為了正確地實例化ModelField,必須傳遞一個附加到實例化模型的字段。例如:ModelField(model_field=MyModel()._meta.get_field('custom_field'))。
這是一個只讀字段。它通過在附加的序列化器類上調(diào)用一個方法來獲取其值。它可以用于將任何類型的數(shù)據(jù)添加到對象的序列化表示中。
簽名: SerializerMethodField(method_name=None)
method_name參數(shù)引用的序列化程序方法應(yīng)接受單個參數(shù)(除了之外self),該參數(shù)是要序列化的對象。它應(yīng)該返回要包含在對象的序列化表示中的任何內(nèi)容。例如:
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
如果要創(chuàng)建自定義字段,則需要繼承Field類,然后重寫.to_representation()和.to_internal_value()方法之一或二者。這兩種方法用于在初始數(shù)據(jù)類型和原始的可序列化數(shù)據(jù)類型之間進(jìn)行轉(zhuǎn)換?;緮?shù)據(jù)類型通常是任何數(shù)字,字符串,布爾,date/time/datetime或None。它們也可以是僅包含其他原始對象的任何列表或字典之類的對象。根據(jù)您使用的渲染器,可能支持其他類型。
.to_representation() 調(diào)用該方法可將初始數(shù)據(jù)類型轉(zhuǎn)換為原始的可序列化數(shù)據(jù)類型。
to_internal_value()調(diào)用該方法可將原始數(shù)據(jù)類型恢復(fù)為其內(nèi)部python表示形式。如果數(shù)據(jù)無效,則此方法應(yīng)拋出一個 serializers.ValidationError。
請注意,WritableField版本2.x中存在的類不再存在。如果該字段支持?jǐn)?shù)據(jù)輸入,則應(yīng)繼承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, blue
class ColorField(serializers.Field):
"""
Color objects are serialized into 'rgb(#, #, #)' notation.
"""
def to_representation(self, obj):
return "rgb(%d, %d, %d)" % (obj.red, obj.green, obj.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)
默認(rèn)情況下,字段值被視為映射到對象上的屬性。如果需要自定義如何訪問和設(shè)置字段值,則需要覆蓋.get_attribute()和/或.get_value()。
例如,讓我們創(chuàng)建一個字段,該字段可用來表示要序列化的對象的類名:
class ClassNameField(serializers.Field):
def get_attribute(self, obj):
# We pass the object instance onto `to_representation`,
# not just the field attribute.
return obj
def to_representation(self, obj):
"""
Serialize the object's class name.
"""
return obj.__class__.__name__
我們上面的ColorField類目前不執(zhí)行任何數(shù)據(jù)驗證。 為了指示無效數(shù)據(jù),我們應(yīng)該引發(fā)一個serializers.ValidationError,如下所示:
def to_internal_value(self, data):
if not isinstance(data, six.text_type):
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()方法是引發(fā)的快捷方式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, six.text_type):
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)
這種樣式使您的錯誤消息與代碼更清晰地分開,因此應(yīng)首選。
以下第三方軟件包也可使用。
drf-compound-fields包提供了“復(fù)合”序列化器字段,例如簡單值列表,可以由其他字段來描述,而不是帶有many = True選項的序列化器。 還提供了用于鍵入字典和值的字段,這些字段可以是特定類型,也可以是該類型的項目的列表。
drf-extra-fields 包為REST框架提供了額外的序列化器字段,包括Base64ImageField和PointField類。
djangorestframework-recursive 包提供了一個RecursiveField,用于序列化和反序列化遞歸結(jié)構(gòu)
django-rest-framework-gis 包為django rest框架提供了地理插件,例如GeometryField字段和GeoJSON序列化器。
The django-rest-framework-hstore 包提供了一個HStoreField來支持 django-hstore DictionaryField 模型字段。
更多建議: