序列化器字段 (Serializer fields)


Form 類中的每個字段不僅負責驗證數據,而且還負責“清理”它 — 將其規范化為一致的格式。—— Django 文檔

序列化器字段處理原始值和內部數據類型之間的轉換。它們還處理驗證輸入值,以及從父對象檢索和設置值。


注意: 序列化器字段都聲明在 fields.py 中,但按照慣例,應該使用 from rest_framework import serializers 導入它們,並引用字段作為 serializers.<FieldName>


核心參數 (Core arguments)

每個序列化器字段類構造函數至少采用這些參數。某些 Field 類采用附加的、字段特定的參數,但應始終接受以下內容:

read_only

只讀字段包含在 API 輸出中,但不應包含在創建或更新操作期間的輸入中。任何不正確地包含在序列化器輸入中的 'read_only' 字段將被忽略。

將此屬性設置為 True 可確保在序列化表示時使用該字段,但在反序列化期間創建或更新實例時不使用該字段。

默認為 False

write_only

將此屬性設置為 True 可確保在更新或創建實例時可以使用該字段,但在序列化表示時不包括該字段。

默認為 False

required

通常,如果在反序列化期間未提供字段,則會引發錯誤。如果在反序列化期間不需要此字段,則設置為 false。

將此屬性設置為 False 還允許在序列化實例時從輸出中省略對象屬性或字典鍵。如果鍵不存在,它就不會包含在輸出表示中。

默認為 True

default

如果設置,則給出默認值,如果未提供輸入值,將使用該字段。如果未設置,則默認行為是不填充該屬性。

部分更新操作時不應用 default。在部分更新的情況下,只有傳入數據中提供的字段將返回驗證值。

可以設置為函數或其他可調用函數,在這種情況下,將在每次使用時評估該值。調用時,它不會收到任何參數。如果可調用函數具有 set_context 方法,那么每次在獲取字段實例作為唯一參數的值之前都會調用該方法。這與驗證器的工作方式相同。

序列化實例時,如果實例中不存在對象屬性或字典鍵,則將使用默認值。

請注意,設置默認值意味着該字段不是必須的。同時包括 default 和 required 的關鍵字參數都是無效的,並且會引發錯誤。

allow_null

如果把 None 傳遞給序列化器字段,通常會引發錯誤。如果 None 應被視為有效值,則將此關鍵字參數設置為 True

請注意,如果沒有顯式的默認值,將此參數設置為 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

用於預填充 HTML 表單字段值的值。您可以將 callable 傳遞給它,就像使用任何常規 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'

# 使用 <input type="password"> 作為輸入。
password = serializers.CharField( style={'input_type': 'password'} ) # 使用單選輸入而不是選擇輸入。 color_channel = serializers.ChoiceField( choices=['red', 'green', 'blue'], style={'base_template': 'radio.html'} ) 

有關更多詳細信息,請參閱 HTML 和表單文檔。


Boolean 字段 (Boolean fields)

BooleanField

布爾表示。

當使用 HTML 編碼表單輸入時,注意省略總是被視為將字段設置為 False 的值,即使它指定了 default=True選項。這是因為 HTML 復選框通過省略該值來表示未選中的狀態,所以 REST framework 將省略看作是空的復選框輸入。

注意,默認的 BooleanField 實例將使用 required=False 選項生成 (因為 Django models.BooleanField 始終為 blank=True)。如果想要更改此行為,請在序列化器類上顯式聲明 BooleanField

對應於 django.db.models.fields.BooleanField

簽名:BooleanField()

NullBooleanField

還接受 None 作為有效值的布爾表示。

對應於 django.db.models.fields.NullBooleanField

簽名:NullBooleanField()


字符串字段 (String fields)

CharField

文本表示。(可選) 驗證文本是否小於 max_length 且長於 min_length

對應於 django.db.models.fields.CharField 或 django.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=True 和 allow_null=True 是有效的,但這樣做意味着字符串表示允許有兩種不同類型的空值,這可能導致數據不一致和微妙的應用程序錯誤。

EmailField

文本表示,將文本驗證為有效的電子郵件地址。

對應於 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 參數可以是字符串,也可以是編譯的 python 正則表達式對象。

使用 Django 的 django.core.validators.RegexValidator 進行驗證。

SlugField

根據模式 [a-zA-Z0-9_-]+ 驗證輸入的 RegexField

對應於 django.db.models.fields.SlugField

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

URLField

根據 URL 匹配模式驗證輸入的 RegexField。期望窗體的完全限定 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

確保輸入是有效 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' —— 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

確保輸入是有效 IPv4 或 IPv6 字符串的字段。

對應於 django.forms.fields.IPAddressField 和 django.forms.fields.GenericIPAddressField

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

  • protocol 限制指定協議的有效輸入。可接受的值是 'both' (默認),'IPv4' 或 'IPv6'。匹配不區分大小寫。
  • unpack_ipv4 解壓 IPv4 映射地址,如 ::ffff:192.0.2.1。如果啟用此選項,則該地址將解壓到 192.0.2.1。默認為禁用。只能在 protocol 設置為 'both' 時使用。

數字字段 (Numeric fields)

IntegerField

整數表示。

對應於 django.db.models.fields.IntegerField, django.db.models.fields.SmallIntegerFielddjango.db.models.fields.PositiveIntegerField 和 django.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

十進制表示,由 Decimal 實例在 Python 中表示。

對應於 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;如果應返回 Decimal 對象,則設置為 False。默認與 COERCE_DECIMAL_TO_STRING 設置中的鍵值相同,除非重寫,否則將為 True。如果序列化器返回 Decimal 對象,則最終輸出格式將由渲染器確定。請注意,設置 localize 會將值強制為 True
  • max_value 驗證所提供的數字不大於這個值。
  • min_value 驗證所提供的數字不小於這個值。
  • localize 設置為 True 以便基於當前區域啟用輸入和輸出本地化。這也將強制 coerce_to_string 為 True。默認為 False。請注意,如果在設置文件中設置了 USE_L10N = True,則會啟用數據格式化。
  • rounding 設置量化到配置精度時使用的舍入模式。有效值是 decimal 模塊舍入模式。默認為 None

用法示例 (Example usage)

要使用 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


日期和時間字段 (Date and time fields)

DateTimeField

日期和時間表示。

對應於 django.db.models.fields.DateTimeField

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

  • format —— 表示輸出格式的字符串。如果未指定,則默認為與 DATETIME_FORMAT 設置鍵相同的值,除非設置,否則將為 'iso-8601'。設置為格式字符串表明 to_representation 返回值應該被強制為字符串輸出。格式字符串描述如下。將此值設置為 None 表明應由 to_representation 返回 Python datetime 對象。在這種情況下,日期時間編碼將由渲染器確定。
  • input_formats —— 表示可用於解析日期的輸入格式的字符串列表。如果未指定,則將使用 DATETIME_INPUT_FORMATS 設置,默認為 ['iso-8601']

DateTimeField 格式字符串。

格式化字符串可以是顯式指定的 Python strftime 格式,也可以是表明使用 ISO 8601 樣式的日期時間的特殊字符串 iso-8601。(例如 '2013-01-29T12:34:56.000000Z')

當格式化日期時間對象使用 None 值時,to_representation 將返回,最終的輸出表示將由渲染器類決定。

auto_now 和 auto_now_add 模型字段。

當使用 ModelSerializer 或 HyperlinkedModelSerializer 時,請注意,任何帶有 auto_now=True 或 auto_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()


選擇字段 (Choice selection fields)

ChoiceField

可以接受有限選項集中的值的字段。

如果相應的模型字段包含 choices=… 參數,則使用 ModelSerializer 自動生成字段。

簽名: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_blank 和 allow_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 選擇下拉菜單中顯示的選項的最大數量。可用於確保自動生成具有非常大的可能選擇的 ChoiceField,而不會阻止模板的渲染。默認是 None
  • html_cutoff_text —— 如果設置,如果在 HTML 選擇下拉菜單中截斷了最大數量的項,則將顯示文本指示符。默認為 "More than {count} items…"

與 ChoiceField 一樣,allow_blank 和 allow_null 都是 ChoiceField 選項都是有效的,但強烈建議只使用一個而不是兩個都用。對於文本選擇,allow_blank 應該是首選,而對於數字或其他非文本選擇,allow_null應該是首選。


文件上傳字段 (File upload fields)

解析器和文件上傳 (Parsers and file uploads.)

FileField 和 ImageField 類只適用於 MultiPartParser 或 FileUploadParser。大多數解析器,例如,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


復合字段 (Composite fields)

ListField

驗證對象列表的字段類。

簽名:ListField(child=<A_FIELD_INSTANCE>, min_length=None, max_length=None)

  • child —— 用於驗證列表中的對象的字段實例。如果未提供此參數,則列表中的對象將不會被驗證。
  • 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>)

  • child —— 用於驗證字典中的值的字段實例。如果未提供此參數,則映射中的值將不會被驗證。

例如,要創建一個驗證字符串到字符串映射的字段,可以這樣寫:

document = DictField(child=CharField()) 

您也可以使用聲明式樣式,與 ListField 一樣。例如:

class DocumentField(DictField): child = CharField() 

HStoreField

與 Django 的 postgres HStoreField 兼容的預配置的 DictField

簽名:HStoreField(child=<A_FIELD_INSTANCE>)

  • child —— 用於驗證字典中的值的字段實例。默認子字段接受空字符串和空值。

請注意,子字段必須是 CharField 的實例,因為 hstore 擴展將值存儲為字符串。

JSONField

驗證傳入數據結構由有效 JSON 基元組成的字段類。在它的交替二進制模式中,它將表示和驗證 JSON 編碼的二進制字符串。

簽名:JSONField(binary)

  • binary —— 如果設置為 True,那么該字段將輸出並驗證 JSON 編碼的字符串,而不是原始數據結構。默認是 False

各種各樣的字段 (Miscellaneous fields)

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

可以綁定到任意模型字段的通用字段。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 

自定義字段 (Custom fields)

如果想要創建自定義字段,則需要子類化 Field,並重寫 .to_representation() 和 .to_internal_value() 方法中的一個或兩個。這兩種方法用於在初始數據類型和原始可序列化數據類型之間進行轉換。原始數據類型通常是數字,字符串,布爾值,date/time/datetime 或 None。它們也可以是任何僅包含其他原始對象的列表或字典。可能支持其他類型,具體取決於您使用的渲染器。

調用 .to_representation() 方法將初始數據類型轉換為原始的可序列化數據類型。

調用 to_internal_value() 方法將原始數據類型恢復為其內部 python 表示。如果數據無效,此方法應該引發 serializers.ValidationError 異常。

請注意,2.x 版本中存在的 WritableField 類不再存在。 如果字段支持數據輸入,則應該子類化 Field 並重寫 to_internal_value()

舉個栗子

基本自定義字段 (A Basic Custom Field)

讓我們來看一個序列化一個表示 RGB 顏色值的類的例子:

class Color(object): """  在 RGB 顏色空間中表示的顏色。  """ 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): """  顏色對象被序列化為 'rgb(#, #, #)' 表示法。  """ 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) 

默認情況下,字段值被視為映射到對象上的屬性。如果需要自定義訪問和設置字段值的方式,則需要重寫 .get_attribute() 和/或 .get_value()

例如,讓我們創建一個用於表示被序列化對象的類名的字段:

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__ 

拋出驗證錯誤 (Raising validation errors)

我們上面的 ColorField 類目前不執行任何數據驗證。要指示無效數據,我們應引發 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() 方法是引發 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) 

這種樣式使您的錯誤信息更清晰,並且代碼更獨立,應該是首選。

使用 source='*'

在這里,我們將以一個帶有 x_coordinate 和 y_coordinate 屬性的平面 DataPoint 模型為例。

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, obj): ret = { "x": obj.x_coordinate, "y": obj.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', 'testing'), ('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'] 

在這里,目標和源屬性對(x 和 x_coordinatey 和 y_coordinate)之間的映射在 IntegerField 聲明中處理。這是使用了 source ='*' 的 NestedCoordinateSerializer

新的 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.']})]) 

由於這個原因,嵌套的序列化器方法將是第一個嘗試。當嵌套的序列化器變得不可行或過於復雜時,您將使用自定義字段方法。

第三方包 (Third party packages)

以下是可用的第三方包。

DRF Compound Fields

drf-compound-fields 包提供“復合”序列化器字段,例如簡單值列表,它可以由其他字段描述,而不是使用 many = True 選項的序列化器。還提供了類型化字典和值的字段,它們可以是特定類型或該類型的項列表。

DRF Extra Fields

drf-extra-fields 包為 REST framework 提供了額外的序列化器字段,包括 Base64ImageField 和 PointField類。

djangorestframework-recursive

djangorestframework-recursive 包為序列化和反序列化遞歸結構提供了 RecursiveField

django-rest-framework-gis

django-rest-framework-gis 包為 django rest framework 提供了地理插件,如 GeometryField 字段和 GeoJSON 序列化器。

django-rest-framework-hstore

django-rest-framework-hstore 包提供了 HStoreField 來支持 django-hstore DictionaryField 模型字段。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM