fields.py

シリアライザーフィールド

Formクラスの各フィールドは、データの検証だけでなく、「クリーンアップ」も担当します。つまり、一貫した形式に正規化します。

Djangoのドキュメント

シリアライザーフィールドは、プリミティブ値と内部データ型間の変換を処理します。 また、入力値の検証、および親オブジェクトからの値の取得と設定も処理します。


注:シリアライザーフィールドはfields.pyで宣言されていますが、慣例としてfrom rest_framework import serializersを使用してインポートし、フィールドをserializers.<FieldName>として参照する必要があります。


コア引数

各シリアライザーフィールドクラスコンストラクターは、少なくともこれらの引数を取ります。 一部のFieldクラスは、フィールド固有の追加の引数を取りますが、常に以下の引数を受け入れる必要があります。

read_only

読み取り専用フィールドはAPI出力に含まれますが、作成または更新操作中の入力には含めないでください。シリアライザー入力に誤って含まれている「read_only」フィールドは無視されます。

この値をTrueに設定すると、表現をシリアライズするときにフィールドが使用されますが、デシリアライズ中にインスタンスを作成または更新するときには使用されなくなります。

デフォルトはFalse

write_only

この値をTrueに設定すると、インスタンスを更新または作成するときにフィールドを使用できますが、表現をシリアライズするときには含められなくなります。

デフォルトはFalse

required

通常、デシリアライズ中にフィールドが指定されていない場合、エラーが発生します。デシリアライズ中にこのフィールドが存在する必要がない場合は、falseに設定します。

これをFalseに設定すると、インスタンスをシリアライズするときに、オブジェクト属性または辞書キーを出力から省略することもできます。キーが存在しない場合は、出力表現に含まれません。

デフォルトはTrueです。 モデルシリアライザーを使用している場合、Modelのフィールドでblank=Truedefault、またはnull=Trueを指定した場合、デフォルト値はFalseになります。

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が使用されます。

default値を設定すると、フィールドが必須ではないことを意味することに注意してください。defaultキーワード引数とrequiredキーワード引数の両方を含めることは無効であり、エラーが発生します。

allow_null

通常、Noneがシリアライザーフィールドに渡されると、エラーが発生します。 Noneを有効な値と見なす場合は、このキーワード引数をTrueに設定します。

明示的なdefaultがない場合、この引数をTrueに設定すると、シリアライズ出力のnulldefault値が暗示されることに注意してください。ただし、入力デシリアライズのデフォルトは暗示しません。

デフォルトはFalse

source

フィールドを設定するために使用される属性の名前。 URLField(source='get_absolute_url')のようにself引数のみを取るメソッドの場合や、EmailField(source='user.email')のようにドット表記を使用して属性をトラバースすることができます。

ドット表記のフィールドをシリアライズする場合、属性トラバース中にオブジェクトが存在しない場合や空の場合は、default値を指定する必要がある場合があります。リレーショナルORMモデルにアクセスしている場合は、source属性を使用する際に発生する可能性のあるn+1問題に注意してください。例:

class CommentSerializer(serializers.Serializer):
    email = serializers.EmailField(source="user.email")

この場合、プリフェッチされていない場合にデータベースからuserオブジェクトをフェッチする必要があります。それが望ましくない場合は、prefetch_relatedメソッドとselect_relatedメソッドを適切に使用してください。メソッドの詳細については、djangoのドキュメントを参照してください。

source='*'には特別な意味があり、オブジェクト全体をフィールドに渡す必要があることを示すために使用されます。これは、ネストされた表現を作成する場合や、出力表現を決定するためにオブジェクト全体へのアクセスを必要とするフィールドの場合に役立ちます。

デフォルトは、フィールドの名前です。

validators

受信フィールド入力に適用する必要があり、検証エラーを発生させるか、単に返すバリデーター関数のリスト。バリデーター関数は通常、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

レンダラーがフィールドをどのようにレンダリングするかを制御するために使用できるキーと値のペアの辞書。

ここでの2つの例は、'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エンコードされたフォーム入力を使用する場合、値を省略すると、default=Trueオプションが指定されていても、常にフィールドをFalseに設定すると見なされることに注意してください。これは、HTMLチェックボックス入力が値を省略することで未チェック状態を表すため、REST frameworkでは省略を空のチェックボックス入力であるかのように扱います。

Django 2.1では、models.BooleanFieldからblank kwargが削除されたことに注意してください。 Django 2.1より前では、models.BooleanFieldフィールドは常にblank=Trueでした。したがって、Django 2.1以降、デフォルトのserializers.BooleanFieldインスタンスはrequired kwargなしで(つまり、required=Trueと同等)生成されますが、以前のバージョンのDjangoでは、デフォルトのBooleanFieldインスタンスはrequired=Falseオプションで生成されます。この動作を手動で制御する場合は、シリアライザー クラスでBooleanFieldを明示的に宣言するか、extra_kwargsオプションを使用してrequiredフラグを設定します。

django.db.models.fields.BooleanFieldに対応。

署名: BooleanField()


文字列フィールド

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=Trueallow_null=True の両方を設定することは可能ですが、その場合、文字列の表現として許容される空の値が2種類存在することになり、データの一貫性の欠如やアプリケーションの微妙なバグにつながる可能性があります。

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 です。 http://<host>/<path> 形式の完全修飾 URL を想定しています。

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' - ハイフンを含む、正規の16進数表現: "5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
    • 'hex' - ハイフンを含まない、UUID のコンパクトな16進数表現: "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 ::ffff:192.0.2.1 のような IPv4 マッピングアドレスをアンパックします。このオプションを有効にすると、そのアドレスは 192.0.2.1 にアンパックされます。デフォルトでは無効になっています。プロトコルが 'both' に設定されている場合にのみ使用できます。

数値フィールド

IntegerField

整数表現です。

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)

  • max_value 指定された数値がこの値以下であることを検証します。
  • min_value 指定された数値がこの値以上であることを検証します。

FloatField

浮動小数点表現です。

django.db.models.fields.FloatField に対応します。

シグネチャ: FloatField(max_value=None, min_value=None)

  • max_value 指定された数値がこの値以下であることを検証します。
  • min_value 指定された数値がこの値以上であることを検証します。

DecimalField

10進数表現で、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 に設定し、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 です。
  • normalize_output シリアライズ時に10進値を正規化します。これにより、すべての末尾のゼロが削除され、データを失うことなく値を表現するために必要な最小精度に値の精度が変更されます。デフォルトは False です。

使用例

小数点以下2桁の精度で最大999までの数値を検証するには、次のように使用します。

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

小数点以下10桁の精度で10億未満の数値を検証するには、次のように使用します。

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

日付と時刻フィールド

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 によって返されることを示します。この場合、datetime のエンコードはレンダラーによって決定されます。
  • input_formats - 日付の解析に使用できる入力形式を表す文字列のリスト。指定されていない場合、DATETIME_INPUT_FORMATS 設定が使用され、デフォルトは ['iso-8601'] です。
  • default_timezone - タイムゾーンを表す tzinfo サブクラス (zoneinfo または pytz)。指定されておらず、USE_TZ 設定が有効になっている場合、これは 現在のタイムゾーンにデフォルト設定されます。USE_TZ が無効になっている場合、datetime オブジェクトはナイーブになります。

DateTimeField 書式文字列。

書式文字列には、書式を明示的に指定する Python strftime 書式、または ISO 8601 スタイルの日時を使用する必要があることを示す特殊な文字列 'iso-8601' を指定できます。(例: '2013-01-29T12:34:56.000000Z')

書式に None の値が使用されると、datetime オブジェクトが 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(max_value=None, min_value=None)

  • max_value 指定された期間がこの値を超えないことを検証します。
  • min_value 指定された期間がこの値より小さくないことを検証します。

選択フィールド

ChoiceField

限られた選択肢の中から値を受け入れることができるフィールド。

対応するモデルフィールドに choices=… 引数が含まれている場合、ModelSerializer によってフィールドを自動的に生成するために使用されます。

署名: 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

限られた選択肢の中から選択された、ゼロ、1つ、または複数の値のセットを受け入れることができるフィールド。必須の引数を1つ取ります。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_blank オプションと allow_null オプションの両方が有効ですが、両方ではなく片方だけを使用することを強くお勧めします。allow_blank はテキストによる選択肢に適しており、allow_null は数値またはその他の非テキストによる選択肢に適しています。


ファイルアップロードフィールド

パーサーとファイルアップロード。

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 パッケージのいずれかが必要です。PIL はアクティブにメンテナンスされなくなったため、Pillow パッケージをお勧めします。


複合フィールド

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()

これで、child 引数を指定せずに、アプリケーション全体でカスタムの StringListField クラスを再利用できます。

DictField

オブジェクトの辞書を検証するフィールドクラス。DictField のキーは常に文字列値であると見なされます。

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

  • child - 辞書内の値の検証に使用する必要があるフィールドインスタンス。この引数が指定されていない場合、マッピング内の値は検証されません。
  • allow_empty - 空の辞書が許可されるかどうかを指定します。

たとえば、文字列から文字列へのマッピングを検証するフィールドを作成するには、次のように記述します。

document = DictField(child=CharField())

ListField と同様に、宣言的なスタイルも使用できます。たとえば、次のようにします。

class DocumentField(DictField):
    child = CharField()

HStoreField

DjangoのPostgres HStoreField と互換性のある事前構成済みの DictField

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

  • child - 辞書内の値の検証に使用されるフィールドインスタンス。デフォルトの子フィールドは、空の文字列とnull値の両方を受け入れます。
  • allow_empty - 空の辞書が許可されるかどうかを指定します。

hstore拡張機能は値を文字列として格納するため、子フィールドは CharField のインスタンスである必要があります。

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 = Account
        fields = ['id', 'account_name', 'has_expired']

HiddenField

ユーザー入力に基づいて値を取得するのではなく、デフォルト値またはcallableから値を取得するフィールドクラス。

署名: HiddenField()

たとえば、シリアライザーの検証済みデータの一部として常に現在の時刻を提供するフィールドを含めるには、次のように使用します。

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

HiddenField クラスは通常、事前に提供されたフィールド値に基づいて実行する必要がある検証があり、これらのフィールドをすべてエンドユーザーに公開したくない場合にのみ必要です。

HiddenField の詳細な例については、バリデーターのドキュメントを参照してください。


注: HiddenField() は、partial=True シリアライザー(PATCH リクエストを作成する場合)には表示されません。この動作は将来変更される可能性があります。 githubディスカッションの更新に従ってください。


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 に加えて)1つの引数を受け入れる必要があります。これは、シリアル化されるオブジェクトです。オブジェクトのシリアル化された表現に含めるものがあれば、それを返す必要があります。例えば

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
        fields = '__all__'

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

カスタムフィールド

カスタムフィールドを作成する場合は、Field をサブクラス化し、.to_representation() メソッドと .to_internal_value() メソッドのいずれかまたは両方をオーバーライドする必要があります。これらの2つのメソッドは、初期データ型とプリミティブでシリアル化可能なデータ型の間を変換するために使用されます。プリミティブデータ型は、通常、数値、文字列、ブール値、date/time/datetime、または None のいずれかになります。また、他のプリミティブオブジェクトのみを含む、リストまたは辞書のようなオブジェクトにすることもできます。使用しているレンダラーによっては、他の型がサポートされる場合があります。

.to_representation() メソッドは、初期データ型をプリミティブでシリアル化可能なデータ型に変換するために呼び出されます。

.to_internal_value() メソッドは、プリミティブデータ型を内部のPython表現に復元するために呼び出されます。データが無効な場合、このメソッドは serializers.ValidationError を発生させる必要があります。

基本的なカスタムフィールド

RGBカラー値を表すクラスをシリアル化する例を見てみましょう。

class Color:
    """
    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() メソッドは、error_messages 辞書からメッセージ文字列を受け取る ValidationError を発生させるためのショートカットです。たとえば

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='*' の使用

ここでは、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, 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='*' を使用したネストされたシリアライザーで、それぞれのフィールドを指す独自の source を持つ2つの IntegerField インスタンスを使用する方が適切かもしれません。

しかし、この例の重要な点は以下のとおりです。

  • 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 は、ターゲットオブジェクトを更新するのに適した dict にマッピングし直す必要があります。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 の宣言で処理されます。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.']})])

このため、ネストされたシリアライザーのアプローチを最初に試すのがよいでしょう。ネストされたシリアライザーが非現実的になったり、過度に複雑になったりした場合に、カスタムフィールドのアプローチを使用することになります。

サードパーティパッケージ

以下のサードパーティパッケージも利用可能です。

DRF Compound Fields

drf-compound-fields パッケージは、単純な値のリストなど、many=True オプションを持つシリアライザーではなく、他のフィールドで記述できる「複合」シリアライザーフィールドを提供します。また、型付き辞書や、特定の型またはその型の項目のリストのいずれかである値のフィールドも提供します。

DRF Extra Fields

drf-extra-fields パッケージは、RESTフレームワーク用の追加のシリアライザーフィールド(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 パッケージは、django-hstoreDictionaryField モデルフィールドをサポートするための HStoreField を提供します。