シリアライザー
シリアライザーの有用性を拡張することは、私たちが取り組みたいことの一つです。しかし、それは簡単な問題ではなく、本格的な設計作業が必要になります。
— Russell Keith-Magee, Django users group
シリアライザーを使用すると、クエリセットやモデルインスタンスなどの複雑なデータを、JSON
、XML
、またはその他のコンテンツタイプに簡単にレンダリングできるネイティブPythonデータ型に変換できます。シリアライザーは、パースされたデータを受信データが最初に検証された後、複雑な型に変換し直すことができるデシリアライズも提供します。
REST frameworkのシリアライザーは、DjangoのForm
およびModelForm
クラスと非常によく似た動作をします。レスポンスの出力を強力かつ汎用的に制御できるSerializer
クラスと、モデルインスタンスおよびクエリセットを処理するシリアライザーを作成するための便利なショートカットを提供するModelSerializer
クラスを提供します。
シリアライザーの宣言
まず、例として使用できる簡単なオブジェクトを作成しましょう
from datetime import datetime
class Comment:
def __init__(self, email, content, created=None):
self.email = email
self.content = content
self.created = created or datetime.now()
comment = Comment(email='leila@example.com', content='foo bar')
Comment
オブジェクトに対応するデータをシリアライズおよびデシリアライズするために使用できるシリアライザーを宣言します。
シリアライザーの宣言は、フォームの宣言と非常によく似ています
from rest_framework import serializers
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
オブジェクトのシリアライズ
これで、CommentSerializer
を使用して、コメントまたはコメントのリストをシリアライズできます。ここでも、Serializer
クラスの使用はForm
クラスの使用によく似ています。
serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}
この時点で、モデルインスタンスをPythonネイティブデータ型に変換しました。シリアライゼーションプロセスを完了するには、データをjson
にレンダリングします。
from rest_framework.renderers import JSONRenderer
json = JSONRenderer().render(serializer.data)
json
# b'{"email":"leila@example.com","content":"foo bar","created":"2016-01-27T15:17:10.375877"}'
オブジェクトのデシリアライズ
デシリアライゼーションも同様です。最初に、ストリームをPythonネイティブデータ型にパースします...
import io
from rest_framework.parsers import JSONParser
stream = io.BytesIO(json)
data = JSONParser().parse(stream)
...次に、これらのネイティブデータ型を検証済みデータの辞書に復元します。
serializer = CommentSerializer(data=data)
serializer.is_valid()
# True
serializer.validated_data
# {'content': 'foo bar', 'email': 'leila@example.com', 'created': datetime.datetime(2012, 08, 22, 16, 20, 09, 822243)}
インスタンスの保存
検証済みデータに基づいて完全なオブジェクトインスタンスを返せるようにするには、.create()
メソッドと.update()
メソッドのいずれかまたは両方を実装する必要があります。たとえば
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
def create(self, validated_data):
return Comment(**validated_data)
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
return instance
オブジェクトインスタンスがDjangoモデルに対応している場合は、これらのメソッドがオブジェクトをデータベースに保存するようにする必要があります。たとえば、Comment
がDjangoモデルの場合、メソッドは次のようになります。
def create(self, validated_data):
return Comment.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
instance.save()
return instance
これで、データをデシリアライズするときに、検証済みデータに基づいてオブジェクトインスタンスを返すために.save()
を呼び出すことができます。
comment = serializer.save()
.save()
を呼び出すと、シリアライザークラスのインスタンス化時に既存のインスタンスが渡されたかどうかに応じて、新しいインスタンスが作成されるか、既存のインスタンスが更新されます。
# .save() will create a new instance.
serializer = CommentSerializer(data=data)
# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
.create()
メソッドと.update()
メソッドは両方ともオプションです。シリアライザークラスのユースケースに応じて、いずれも実装しないか、いずれか1つまたは両方を実装できます。
.save()
に追加の属性を渡す
インスタンスを保存するときに、ビューコードが追加のデータをインジェクトできるようにしたい場合があります。この追加データには、現在のユーザー、現在の時刻、またはリクエストデータの一部ではないその他の情報を含めることができます。
.save()
を呼び出すときに追加のキーワード引数を含めることで、それを行うことができます。たとえば
serializer.save(owner=request.user)
追加のキーワード引数は、.create()
または.update()
が呼び出されるときに、validated_data
引数に含められます。
.save()
を直接オーバーライドする。
場合によっては、.create()
メソッドと.update()
メソッドの名前が意味を持たない場合があります。たとえば、お問い合わせフォームでは、新しいインスタンスを作成するのではなく、メールやその他のメッセージを送信する場合があります。
このような場合は、より読みやすく意味のあるものとして、代わりに.save()
を直接オーバーライドすることを選択できます。
たとえば
class ContactForm(serializers.Serializer):
email = serializers.EmailField()
message = serializers.CharField()
def save(self):
email = self.validated_data['email']
message = self.validated_data['message']
send_email(from=email, message=message)
上記の例では、シリアライザーの.validated_data
プロパティに直接アクセスする必要があることに注意してください。
バリデーション
データをデシリアライズするときは、検証済みデータにアクセスしたり、オブジェクトインスタンスを保存したりする前に、常にis_valid()
を呼び出す必要があります。検証エラーが発生した場合、.errors
プロパティには、結果のエラーメッセージを表す辞書が含まれます。たとえば
serializer = CommentSerializer(data={'email': 'foobar', 'content': 'baz'})
serializer.is_valid()
# False
serializer.errors
# {'email': ['Enter a valid e-mail address.'], 'created': ['This field is required.']}
辞書の各キーはフィールド名になり、値は、そのフィールドに対応するエラーメッセージの文字列のリストになります。non_field_errors
キーも存在する可能性があり、一般的な検証エラーがリストされます。non_field_errors
キーの名前は、NON_FIELD_ERRORS_KEY
REST framework設定を使用してカスタマイズできます。
項目のリストをデシリアライズすると、エラーは、デシリアライズされた各項目を表す辞書のリストとして返されます。
無効なデータで例外を発生させる
.is_valid()
メソッドは、検証エラーがある場合にserializers.ValidationError
例外を発生させるオプションのraise_exception
フラグを取ります。
これらの例外は、REST frameworkが提供するデフォルトの例外ハンドラーによって自動的に処理され、デフォルトでHTTP 400 Bad Request
レスポンスを返します。
# Return a 400 response if the data was invalid.
serializer.is_valid(raise_exception=True)
フィールドレベルのバリデーション
.validate_<field_name>
メソッドをSerializer
サブクラスに追加することで、カスタムのフィールドレベルのバリデーションを指定できます。これらは、Djangoフォームの.clean_<field_name>
メソッドに似ています。
これらのメソッドは、検証が必要なフィールド値である単一の引数を取ります。
validate_<field_name>
メソッドは、検証済みの値を返すか、serializers.ValidationError
を発生させる必要があります。たとえば
from rest_framework import serializers
class BlogPostSerializer(serializers.Serializer):
title = serializers.CharField(max_length=100)
content = serializers.CharField()
def validate_title(self, value):
"""
Check that the blog post is about Django.
"""
if 'django' not in value.lower():
raise serializers.ValidationError("Blog post is not about Django")
return value
注: <field_name>
がシリアライザーでパラメータrequired=False
で宣言されている場合、フィールドが含まれていない場合、この検証ステップは実行されません。
オブジェクトレベルのバリデーション
複数のフィールドへのアクセスを必要とするその他の検証を行うには、.validate()
というメソッドをSerializer
サブクラスに追加します。このメソッドは、フィールド値の辞書である単一の引数を受け取ります。必要に応じてserializers.ValidationError
を発生させるか、検証済みの値を返すだけです。たとえば
from rest_framework import serializers
class EventSerializer(serializers.Serializer):
description = serializers.CharField(max_length=100)
start = serializers.DateTimeField()
finish = serializers.DateTimeField()
def validate(self, data):
"""
Check that start is before finish.
"""
if data['start'] > data['finish']:
raise serializers.ValidationError("finish must occur after start")
return data
バリデーター
シリアライザーの個々のフィールドには、フィールドインスタンスで宣言することにより、バリデーターを含めることができます。たとえば
def multiple_of_ten(value):
if value % 10 != 0:
raise serializers.ValidationError('Not a multiple of ten')
class GameRecord(serializers.Serializer):
score = serializers.IntegerField(validators=[multiple_of_ten])
...
シリアライザークラスには、フィールドデータの完全なセットに適用される再利用可能なバリデーターを含めることもできます。これらのバリデーターは、次のように、内部のMeta
クラスで宣言することにより含められます
class EventSerializer(serializers.Serializer):
name = serializers.CharField()
room_number = serializers.IntegerField(choices=[101, 102, 103, 201])
date = serializers.DateField()
class Meta:
# Each room only has one event per day.
validators = [
UniqueTogetherValidator(
queryset=Event.objects.all(),
fields=['room_number', 'date']
)
]
詳細については、バリデーターのドキュメントを参照してください。
初期データとインスタンスへのアクセス
初期オブジェクトまたはクエリセットをシリアライザーインスタンスに渡すと、オブジェクトは.instance
として使用できるようになります。初期オブジェクトが渡されない場合、.instance
属性はNone
になります。
データをシリアライザーインスタンスに渡すと、変更されていないデータは.initial_data
として使用できるようになります。data
キーワード引数が渡されない場合、.initial_data
属性は存在しません。
部分更新
デフォルトでは、シリアライザーには、すべての必須フィールドの値が渡される必要があります。そうしないと、検証エラーが発生します。部分更新を許可するために、partial
引数を使用できます。
# Update `comment` with partial data
serializer = CommentSerializer(comment, data={'content': 'foo bar'}, partial=True)
ネストされたオブジェクトの処理
前の例は、単純なデータ型のみを持つオブジェクトを処理する場合は問題ありませんが、オブジェクトの属性の一部が文字列、日付、整数などの単純なデータ型ではない、より複雑なオブジェクトを表す必要もある場合があります。
Serializer
クラス自体がField
の一種であり、オブジェクトタイプが別のオブジェクトタイプ内にネストされている関係を表すために使用できます。
class UserSerializer(serializers.Serializer):
email = serializers.EmailField()
username = serializers.CharField(max_length=100)
class CommentSerializer(serializers.Serializer):
user = UserSerializer()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
ネストされた表現でNone
値をオプションとして受け入れる場合は、ネストされたシリアライザーにrequired=False
フラグを渡す必要があります。
class CommentSerializer(serializers.Serializer):
user = UserSerializer(required=False) # May be an anonymous user.
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
同様に、ネストされた表現がアイテムのリストである必要がある場合は、ネストされたシリアライザーにmany=True
フラグを渡す必要があります。
class CommentSerializer(serializers.Serializer):
user = UserSerializer(required=False)
edits = EditItemSerializer(many=True) # A nested list of 'edit' items.
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
書き込み可能なネストされた表現
データのデシリアライズをサポートするネストされた表現を扱う場合、ネストされたオブジェクトのエラーはすべて、ネストされたオブジェクトのフィールド名の下にネストされます。
serializer = CommentSerializer(data={'user': {'email': 'foobar', 'username': 'doe'}, 'content': 'baz'})
serializer.is_valid()
# False
serializer.errors
# {'user': {'email': ['Enter a valid e-mail address.']}, 'created': ['This field is required.']}
同様に、.validated_data
プロパティには、ネストされたデータ構造が含まれます。
ネストされた表現のための.create()
メソッドの記述
書き込み可能なネストされた表現をサポートする場合は、複数のオブジェクトの保存を処理する.create()
または.update()
メソッドを記述する必要があります。
次の例は、ネストされたプロファイルオブジェクトを使用してユーザーを作成する方法を示しています。
class UserSerializer(serializers.ModelSerializer):
profile = ProfileSerializer()
class Meta:
model = User
fields = ['username', 'email', 'profile']
def create(self, validated_data):
profile_data = validated_data.pop('profile')
user = User.objects.create(**validated_data)
Profile.objects.create(user=user, **profile_data)
return user
ネストされた表現のための.update()
メソッドの記述
更新の場合、関係の更新をどのように処理するかを慎重に検討する必要があります。たとえば、関係のデータがNone
である場合、または提供されていない場合、次のうちどれが発生する必要がありますか?
- データベース内の関係を
NULL
に設定します。 - 関連付けられたインスタンスを削除します。
- データを無視し、インスタンスをそのままにします。
- 検証エラーを発生させます。
以前のUserSerializer
クラスの.update()
メソッドの例を次に示します。
def update(self, instance, validated_data):
profile_data = validated_data.pop('profile')
# Unless the application properly enforces that this field is
# always set, the following could raise a `DoesNotExist`, which
# would need to be handled.
profile = instance.profile
instance.username = validated_data.get('username', instance.username)
instance.email = validated_data.get('email', instance.email)
instance.save()
profile.is_premium_member = profile_data.get(
'is_premium_member',
profile.is_premium_member
)
profile.has_support_contract = profile_data.get(
'has_support_contract',
profile.has_support_contract
)
profile.save()
return instance
ネストされた作成と更新の動作は曖昧になる可能性があり、関連するモデル間で複雑な依存関係が必要になる場合があるため、RESTフレームワーク3では、これらのメソッドを常に明示的に記述する必要があります。デフォルトのModelSerializer
の.create()
および.update()
メソッドには、書き込み可能なネストされた表現のサポートは含まれていません。
ただし、DRF Writable Nestedなどの自動書き込み可能なネストされた表現をサポートするサードパーティパッケージが利用可能です。
モデルマネージャクラスでの関連インスタンスの保存の処理
シリアライザーで複数の関連インスタンスを保存する代わりに、正しいインスタンスの作成を処理するカスタムモデルマネージャクラスを作成する方法があります。
たとえば、User
インスタンスとProfile
インスタンスが常にペアとして一緒に作成されるようにする必要があるとします。次のようなカスタムマネージャクラスを作成できます。
class UserManager(models.Manager):
...
def create(self, username, email, is_premium_member=False, has_support_contract=False):
user = User(username=username, email=email)
user.save()
profile = Profile(
user=user,
is_premium_member=is_premium_member,
has_support_contract=has_support_contract
)
profile.save()
return user
このマネージャクラスは、ユーザーインスタンスとプロファイルインスタンスが常に同時に作成されることをより適切にカプセル化するようになりました。シリアライザークラスの.create()
メソッドを、新しいマネージャメソッドを使用するように書き換えることができます。
def create(self, validated_data):
return User.objects.create(
username=validated_data['username'],
email=validated_data['email'],
is_premium_member=validated_data['profile']['is_premium_member'],
has_support_contract=validated_data['profile']['has_support_contract']
)
このアプローチの詳細については、Djangoドキュメントのモデルマネージャと、モデルクラスとマネージャクラスの使用に関するこのブログ記事を参照してください。
複数のオブジェクトの処理
Serializer
クラスは、オブジェクトのリストのシリアライズまたはデシリアライズも処理できます。
複数のオブジェクトのシリアライズ
単一のオブジェクトインスタンスではなく、クエリセットまたはオブジェクトのリストをシリアライズするには、シリアライザーをインスタンス化するときにmany=True
フラグを渡す必要があります。次に、シリアライズするクエリセットまたはオブジェクトのリストを渡すことができます。
queryset = Book.objects.all()
serializer = BookSerializer(queryset, many=True)
serializer.data
# [
# {'id': 0, 'title': 'The electric kool-aid acid test', 'author': 'Tom Wolfe'},
# {'id': 1, 'title': 'If this is a man', 'author': 'Primo Levi'},
# {'id': 2, 'title': 'The wind-up bird chronicle', 'author': 'Haruki Murakami'}
# ]
複数のオブジェクトのデシリアライズ
複数のオブジェクトをデシリアライズするためのデフォルトの動作は、複数のオブジェクトの作成をサポートしますが、複数のオブジェクトの更新はサポートしません。これらのケースをサポートまたはカスタマイズする方法の詳細については、以下のListSerializerドキュメントを参照してください。
追加のコンテキストの組み込み
シリアライズするオブジェクトに加えて、追加のコンテキストをシリアライザーに提供する必要がある場合があります。一般的なケースの1つは、ハイパーリンクされた関係を含むシリアライザーを使用している場合です。これには、完全に修飾されたURLを適切に生成するために、シリアライザーが現在のリクエストにアクセスできる必要があります。
シリアライザーをインスタンス化するときにcontext
引数を渡すことで、任意の追加のコンテキストを提供できます。例:
serializer = AccountSerializer(account, context={'request': request})
serializer.data
# {'id': 6, 'owner': 'denvercoder9', 'created': datetime.datetime(2013, 2, 12, 09, 44, 56, 678870), 'details': 'http://example.com/accounts/6/details'}
コンテキストディクショナリは、self.context
属性にアクセスすることで、カスタムの.to_representation()
メソッドなど、任意のシリアライザーフィールドロジック内で使用できます。
ModelSerializer
多くの場合、Djangoモデル定義に密接に対応するシリアライザークラスが必要になります。
ModelSerializer
クラスは、モデルフィールドに対応するフィールドを持つSerializer
クラスを自動的に作成できるショートカットを提供します。
ModelSerializer
クラスは、通常のSerializer
クラスと同じですが、次の点が異なります。:
- モデルに基づいて、フィールドのセットを自動的に生成します。
- unique_togetherバリデーターなどのシリアライザーのバリデーターを自動的に生成します。
.create()
および.update()
の単純なデフォルト実装が含まれています。
ModelSerializer
の宣言は次のようになります。
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'account_name', 'users', 'created']
デフォルトでは、クラスのすべてのモデルフィールドは、対応するシリアライザーフィールドにマップされます。
モデルの外部キーなどの関係は、PrimaryKeyRelatedField
にマップされます。逆関係は、シリアライザー関係のドキュメントで指定されているように明示的に含めない限り、デフォルトでは含まれません。
ModelSerializer
の検査
シリアライザークラスは、フィールドの状態を完全に検査できる便利な詳細表現文字列を生成します。これは、自動的に作成されるフィールドとバリデーターのセットを決定する場合に、ModelSerializers
を使用する場合に特に役立ちます。
これを行うには、python manage.py shell
を使用してDjangoシェルを開き、シリアライザークラスをインポートし、インスタンス化して、オブジェクト表現を出力します。
>>> from myapp.serializers import AccountSerializer
>>> serializer = AccountSerializer()
>>> print(repr(serializer))
AccountSerializer():
id = IntegerField(label='ID', read_only=True)
name = CharField(allow_blank=True, max_length=100, required=False)
owner = PrimaryKeyRelatedField(queryset=User.objects.all())
含めるフィールドの指定
モデルシリアライザーで使用するデフォルトフィールドのサブセットのみが必要な場合は、ModelForm
の場合と同様に、fields
またはexclude
オプションを使用できます。モデルが変更されたときに意図せずにデータを公開する可能性を低くするために、fields
属性を使用してシリアライズする必要があるすべてのフィールドを明示的に設定することを強くお勧めします。
たとえば
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'account_name', 'users', 'created']
fields
属性を特別な値'__all__'
に設定して、モデルのすべてのフィールドを使用する必要があることを示すこともできます。
たとえば
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = '__all__'
exclude
属性をシリアライザーから除外するフィールドのリストに設定できます。
たとえば
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
exclude = ['users']
上記の例では、Account
モデルに3つのフィールドaccount_name
、users
、およびcreated
がある場合、これによりフィールドaccount_name
とcreated
がシリアライズされます。
fields
属性とexclude
属性の名前は通常、モデルクラスのモデルフィールドにマップされます。
または、fields
オプションの名前は、モデルクラスに存在する引数を取らないプロパティまたはメソッドにマップできます。
バージョン3.3.0以降、fields
またはexclude
のいずれかの属性を提供することは**必須**です。
ネストされたシリアライゼーションの指定
デフォルトのModelSerializer
は関係にプライマリキーを使用しますが、depth
オプションを使用してネストされた表現を簡単に生成することもできます。
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'account_name', 'users', 'created']
depth = 1
depth
オプションは、フラット表現に戻る前にトラバースする必要がある関係の深さを示す整数値に設定する必要があります。
シリアライズの方法をカスタマイズする場合は、フィールドを自分で定義する必要があります。
フィールドの明示的な指定
ModelSerializer
に余分なフィールドを追加したり、クラスでフィールドを宣言することでデフォルトのフィールドをオーバーライドしたりできます。これはSerializer
クラスの場合と同じです。
class AccountSerializer(serializers.ModelSerializer):
url = serializers.CharField(source='get_absolute_url', read_only=True)
groups = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = Account
fields = ['url', 'groups']
余分なフィールドは、モデルの任意のプロパティまたは呼び出し可能に対応できます。
読み取り専用フィールドの指定
複数のフィールドを読み取り専用として指定したい場合があります。read_only=True
属性を持つ各フィールドを明示的に追加する代わりに、ショートカットメタオプションread_only_fields
を使用できます。
このオプションは、フィールド名のリストまたはタプルである必要があり、次のように宣言されます。
class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'account_name', 'users', 'created']
read_only_fields = ['account_name']
editable=False
が設定されているモデルフィールドとAutoField
フィールドは、デフォルトで読み取り専用に設定されるため、read_only_fields
オプションに追加する必要はありません。
注:読み取り専用フィールドがモデルレベルでunique_together
制約の一部である特別なケースがあります。この場合、フィールドは制約を検証するためにシリアライザークラスで必要ですが、ユーザーが編集可能であってはなりません。
これに対処する適切な方法は、シリアライザーでフィールドを明示的に指定し、read_only=True
とdefault=…
キーワード引数の両方を提供することです。
この例の1つは、現在認証されているUser
への読み取り専用の関係であり、これは別の識別子とunique_together
です。この場合、ユーザーフィールドは次のように宣言します。
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
バリデーターのドキュメントで、UniqueTogetherValidatorクラスとCurrentUserDefaultクラスの詳細を確認してください。
追加のキーワード引数
extra_kwargs
オプションを使用して、フィールドに任意の追加キーワード引数を指定できるショートカットもあります。read_only_fields
の場合と同様に、これはシリアライザーでフィールドを明示的に宣言する必要がないことを意味します。
このオプションは、フィールド名をキーワード引数のディクショナリにマッピングするディクショナリです。例:
class CreateUserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['email', 'username', 'password']
extra_kwargs = {'password': {'write_only': True}}
def create(self, validated_data):
user = User(
email=validated_data['email'],
username=validated_data['username']
)
user.set_password(validated_data['password'])
user.save()
return user
フィールドがシリアライザークラスで明示的に宣言されている場合は、extra_kwargs
オプションは無視されることに注意してください。
リレーショナルフィールド
モデルインスタンスをシリアライズする場合、関係を表すためにさまざまな方法を選択できます。ModelSerializer
のデフォルトの表現は、関連インスタンスのプライマリキーを使用することです。
代替表現には、ハイパーリンクを使用したシリアライズ、完全にネストされた表現を使用したシリアライズ、またはカスタム表現を使用したシリアライズが含まれます。
詳細については、シリアライザー関係ドキュメントを参照してください。
フィールドマッピングのカスタマイズ
ModelSerializerクラスは、シリアライザーをインスタンス化するときにシリアライザーフィールドが自動的に決定される方法を変更するためにオーバーライドできるAPIも公開しています。
通常、ModelSerializer
が必要なフィールドをデフォルトで生成しない場合は、それらをクラスに明示的に追加するか、代わりに通常のSerializer
クラスを使用する必要があります。ただし、場合によっては、特定のモデルに対してシリアライザーフィールドがどのように作成されるかを定義する新しい基本クラスを作成する必要がある場合があります。
serializer_field_mapping
DjangoモデルフィールドからRESTフレームワークシリアライザーフィールドへのマッピング。このマッピングをオーバーライドして、各モデルフィールドに使用する必要があるデフォルトのシリアライザーフィールドを変更できます。
serializer_related_field
このプロパティは、デフォルトでリレーショナルフィールドに使用されるシリアライザーフィールドクラスである必要があります。
ModelSerializer
の場合、これはデフォルトでserializers.PrimaryKeyRelatedField
になります。
HyperlinkedModelSerializer
の場合、これはデフォルトでserializers.HyperlinkedRelatedField
になります。
serializer_url_field
シリアライザーのurl
フィールドに使用する必要があるシリアライザーフィールドクラス。
デフォルトはserializers.HyperlinkedIdentityField
です。
serializer_choice_field
シリアライザーの選択フィールドに使用する必要があるシリアライザーフィールドクラス。
デフォルトはserializers.ChoiceField
です。
field_classおよびfield_kwargs API
次のメソッドは、シリアライザーに自動的に含める必要がある各フィールドのクラスとキーワード引数を決定するために呼び出されます。これらの各メソッドは、(field_class, field_kwargs)
の2つのタプルを返す必要があります。
build_standard_field(self, field_name, model_field)
標準モデルフィールドにマップされるシリアライザーフィールドを生成するために呼び出されます。
デフォルトの実装では、serializer_field_mapping
属性に基づいてシリアライザークラスが返されます。
build_relational_field(self, field_name, relation_info)
リレーショナルモデルフィールドにマップされるシリアライザーフィールドを生成するために呼び出されます。
デフォルトの実装では、serializer_related_field
属性に基づいてシリアライザークラスが返されます。
relation_info
引数は、model_field
、related_model
、to_many
、およびhas_through_model
プロパティを含む名前付きタプルです。
build_nested_field(self, field_name, relation_info, nested_depth)
depth
オプションが設定されている場合に、リレーショナルモデルのフィールドにマッピングするシリアライザーフィールドを生成するために呼び出されます。
デフォルトの実装では、ModelSerializer
またはHyperlinkedModelSerializer
のいずれかに基づいて、ネストされたシリアライザークラスを動的に作成します。
nested_depth
は、depth
オプションの値から1を引いた値になります。
relation_info
引数は、model_field
、related_model
、to_many
、およびhas_through_model
プロパティを含む名前付きタプルです。
build_property_field(self, field_name, model_class)
モデルクラスのプロパティまたは引数なしのメソッドにマッピングするシリアライザーフィールドを生成するために呼び出されます。
デフォルトの実装では、ReadOnlyField
クラスを返します。
build_url_field(self, field_name, model_class)
シリアライザー自身のurl
フィールドのシリアライザーフィールドを生成するために呼び出されます。デフォルトの実装では、HyperlinkedIdentityField
クラスを返します。
build_unknown_field(self, field_name, model_class)
フィールド名がモデルフィールドまたはモデルプロパティのいずれにもマッピングされなかった場合に呼び出されます。デフォルトの実装ではエラーが発生しますが、サブクラスはこの動作をカスタマイズできます。
HyperlinkedModelSerializer
HyperlinkedModelSerializer
クラスは、プライマリキーではなくハイパーリンクを使用してリレーションシップを表すことを除いて、ModelSerializer
クラスに似ています。
デフォルトでは、シリアライザーはプライマリキーフィールドの代わりにurl
フィールドを含みます。
urlフィールドはHyperlinkedIdentityField
シリアライザーフィールドを使用して表され、モデル上のリレーションシップはHyperlinkedRelatedField
シリアライザーフィールドを使用して表されます。
例えば、fields
オプションにプライマリキーを追加することで、明示的に含めることができます。
class AccountSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Account
fields = ['url', 'id', 'account_name', 'users', 'created']
絶対URLと相対URL
例えば、HyperlinkedModelSerializer
をインスタンス化するときは、シリアライザーコンテキストに現在のrequest
を含める必要があります。
serializer = AccountSerializer(queryset, context={'request': request})
これにより、ハイパーリンクに適切なホスト名を含めることが保証され、結果として得られる表現は、次のような完全修飾URLを使用します。
http://api.example.com/accounts/1/
次のような相対URLではなく。
/accounts/1/
相対URLを使用する場合は、シリアライザーコンテキストで{'request': None}
を明示的に渡す必要があります。
ハイパーリンクビューがどのように決定されるか
モデルインスタンスへのハイパーリンクに使用するビューを決定する方法が必要です。
デフォルトでは、ハイパーリンクは'{model_name}-detail'
というスタイルに一致し、pk
キーワード引数でインスタンスをルックアップするビュー名に対応することが期待されています。
例えば、extra_kwargs
設定でview_name
オプションとlookup_field
オプションのいずれかまたは両方を使用することで、URLフィールドのビュー名とルックアップフィールドを上書きできます。
class AccountSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Account
fields = ['account_url', 'account_name', 'users', 'created']
extra_kwargs = {
'url': {'view_name': 'accounts', 'lookup_field': 'account_name'},
'users': {'lookup_field': 'username'}
}
または、例えば、シリアライザーのフィールドを明示的に設定することもできます。
class AccountSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='accounts',
lookup_field='slug'
)
users = serializers.HyperlinkedRelatedField(
view_name='user-detail',
lookup_field='username',
many=True,
read_only=True
)
class Meta:
model = Account
fields = ['url', 'account_name', 'users', 'created']
ヒント: ハイパーリンク表現とURL構成を適切に一致させるのは、やや面倒な場合があります。HyperlinkedModelSerializer
インスタンスのrepr
を印刷することは、リレーションシップがマップされることが期待されるビュー名とルックアップフィールドを正確に検査する上で特に便利な方法です。
URLフィールド名の変更
URLフィールドの名前はデフォルトで'url'です。これは、URL_FIELD_NAME
設定を使用することでグローバルに上書きできます。
ListSerializer
ListSerializer
クラスは、複数のオブジェクトを一度にシリアライズおよび検証するための動作を提供します。通常、ListSerializer
を直接使用する必要はありませんが、シリアライザーをインスタンス化するときにmany=True
を渡すだけで済みます。
シリアライザーがインスタンス化され、many=True
が渡されると、ListSerializer
インスタンスが作成されます。その後、シリアライザークラスは親のListSerializer
の子になります。
次の引数を、ListSerializer
フィールドまたはmany=True
が渡されたシリアライザーに渡すこともできます。
allow_empty
これはデフォルトでTrue
ですが、空のリストを有効な入力として許可しない場合はFalse
に設定できます。
max_length
これはデフォルトでNone
ですが、リストにこの数以下の要素しか含まれていないことを検証する場合は、正の整数に設定できます。
min_length
これはデフォルトでNone
ですが、リストにこの数以上の要素が含まれていることを検証する場合は、正の整数に設定できます。
ListSerializer
の動作のカスタマイズ
ListSerializer
の動作をカスタマイズしたい場合がいくつかあります。例えば
- リストの特定の検証を提供したい場合、たとえば、リスト内の1つの要素が別の要素と競合しないことを確認する場合。
- 複数のオブジェクトの作成または更新の動作をカスタマイズしたい場合。
これらのケースでは、many=True
が渡されたときに使用されるクラスを、シリアライザーのMeta
クラスのlist_serializer_class
オプションを使用して変更できます。
たとえば
class CustomListSerializer(serializers.ListSerializer):
...
class CustomSerializer(serializers.Serializer):
...
class Meta:
list_serializer_class = CustomListSerializer
複数の作成のカスタマイズ
複数のオブジェクト作成のデフォルトの実装は、リスト内の各項目に対して.create()
を呼び出すだけです。この動作をカスタマイズしたい場合は、many=True
が渡されたときに使用されるListSerializer
クラスの.create()
メソッドをカスタマイズする必要があります。
たとえば
class BookListSerializer(serializers.ListSerializer):
def create(self, validated_data):
books = [Book(**item) for item in validated_data]
return Book.objects.bulk_create(books)
class BookSerializer(serializers.Serializer):
...
class Meta:
list_serializer_class = BookListSerializer
複数の更新のカスタマイズ
デフォルトでは、ListSerializer
クラスは複数の更新をサポートしていません。これは、挿入と削除に期待される動作があいまいであるためです。
複数の更新をサポートするには、明示的に行う必要があります。複数の更新コードを作成するときは、次の点に留意してください。
- データのリスト内の各項目に対して、どのインスタンスを更新する必要があるかをどのように判断しますか?
- 挿入はどのように処理する必要がありますか?それらは無効ですか、それとも新しいオブジェクトを作成しますか?
- 削除はどのように処理する必要がありますか?オブジェクトの削除、またはリレーションシップの削除を意味しますか?それらは黙って無視されるべきですか、それとも無効ですか?
- 順序はどのように処理する必要がありますか?2つの項目の位置を変更すると、状態が変更されることを意味しますか、それとも無視されますか?
インスタンスシリアライザーに明示的なid
フィールドを追加する必要があります。デフォルトの暗黙的に生成されたid
フィールドはread_only
としてマークされています。これにより、更新時に削除されます。明示的に宣言すると、リストシリアライザーのupdate
メソッドで使用できるようになります。
複数の更新を実装する方法の例を次に示します。
class BookListSerializer(serializers.ListSerializer):
def update(self, instance, validated_data):
# Maps for id->instance and id->data item.
book_mapping = {book.id: book for book in instance}
data_mapping = {item['id']: item for item in validated_data}
# Perform creations and updates.
ret = []
for book_id, data in data_mapping.items():
book = book_mapping.get(book_id, None)
if book is None:
ret.append(self.child.create(data))
else:
ret.append(self.child.update(book, data))
# Perform deletions.
for book_id, book in book_mapping.items():
if book_id not in data_mapping:
book.delete()
return ret
class BookSerializer(serializers.Serializer):
# We need to identify elements in the list using their primary key,
# so use a writable field here, rather than the default which would be read-only.
id = serializers.IntegerField()
...
class Meta:
list_serializer_class = BookListSerializer
RESTフレームワーク2に存在していたallow_add_remove
の動作と同様に、複数の更新操作の自動サポートを提供するサードパーティパッケージが3.1リリースに同梱される可能性があります。
ListSerializerの初期化のカスタマイズ
many=True
のシリアライザーがインスタンス化されたとき、子Serializer
クラスと親ListSerializer
クラスの両方の.__init__()
メソッドに渡す必要がある引数とキーワード引数を決定する必要があります。
デフォルトの実装では、validators
と、子シリアライザーのクラスを対象とすると想定されるカスタムキーワード引数を除く、すべての引数を両方のクラスに渡します。
場合によっては、many=True
が渡されたときに子クラスと親クラスをどのようにインスタンス化する必要があるかを明示的に指定する必要がある場合があります。これは、many_init
クラスメソッドを使用することで実行できます。
@classmethod
def many_init(cls, *args, **kwargs):
# Instantiate the child serializer.
kwargs['child'] = cls()
# Instantiate the parent list serializer.
return CustomListSerializer(*args, **kwargs)
BaseSerializer
代替のシリアル化およびデシリアル化スタイルを簡単にサポートするために使用できるBaseSerializer
クラス。
このクラスは、Serializer
クラスと同じ基本的なAPIを実装します。
.data
- 出力されるプリミティブな表現を返します。.is_valid()
- 入力データをデシリアライズして検証します。.validated_data
- 検証された入力データを返します。.errors
- 検証中のエラーを返します。.save()
- 検証されたデータをオブジェクトインスタンスに永続化します。
シリアライザークラスがサポートする機能に応じて、オーバーライドできる4つのメソッドがあります。
.to_representation()
- 読み取り操作のシリアル化をサポートするために、これをオーバーライドします。.to_internal_value()
- 書き込み操作のデシリアル化をサポートするために、これをオーバーライドします。.create()
および.update()
- インスタンスの保存をサポートするために、これらいずれかまたは両方をオーバーライドします。
このクラスはSerializer
クラスと同じインターフェイスを提供するため、通常のSerializer
またはModelSerializer
の場合とまったく同じように、既存の汎用クラスベースのビューで使用できます。
実行時に気付く唯一の違いは、BaseSerializer
クラスがブラウズ可能なAPIでHTMLフォームを生成しないことです。これは、それらが返すデータに、各フィールドを適切なHTML入力にレンダリングできるようにするすべてのフィールド情報が含まれていないためです。
読み取り専用のBaseSerializer
クラス
BaseSerializer
クラスを使用して読み取り専用のシリアライザーを実装するには、.to_representation()
メソッドをオーバーライドするだけです。単純なDjangoモデルを使用した例を見てみましょう。
class HighScore(models.Model):
created = models.DateTimeField(auto_now_add=True)
player_name = models.CharField(max_length=10)
score = models.IntegerField()
HighScore
インスタンスをプリミティブなデータ型に変換するための読み取り専用シリアライザーを作成するのは簡単です。
class HighScoreSerializer(serializers.BaseSerializer):
def to_representation(self, instance):
return {
'score': instance.score,
'player_name': instance.player_name
}
このクラスを使用して、単一のHighScore
インスタンスをシリアライズできるようになりました。
@api_view(['GET'])
def high_score(request, pk):
instance = HighScore.objects.get(pk=pk)
serializer = HighScoreSerializer(instance)
return Response(serializer.data)
または、複数のインスタンスをシリアライズするために使用することもできます。
@api_view(['GET'])
def all_high_scores(request):
queryset = HighScore.objects.order_by('-score')
serializer = HighScoreSerializer(queryset, many=True)
return Response(serializer.data)
読み書きのBaseSerializer
クラス
読み書きシリアライザーを作成するには、最初に.to_internal_value()
メソッドを実装する必要があります。このメソッドは、オブジェクトインスタンスの構築に使用される検証済みの値を返し、提供されたデータの形式が正しくない場合は、serializers.ValidationError
を発生させる可能性があります。
.to_internal_value()
を実装すると、シリアライザーで基本的な検証APIが使用可能になり、.is_valid()
、.validated_data
、および.errors
を使用できるようになります。
.save()
もサポートする場合は、.create()
メソッドと.update()
メソッドのいずれかまたは両方も実装する必要があります。
読み取りと書き込みの両方の操作をサポートするように更新された、以前のHighScoreSerializer
の完全な例を次に示します。
class HighScoreSerializer(serializers.BaseSerializer):
def to_internal_value(self, data):
score = data.get('score')
player_name = data.get('player_name')
# Perform the data validation.
if not score:
raise serializers.ValidationError({
'score': 'This field is required.'
})
if not player_name:
raise serializers.ValidationError({
'player_name': 'This field is required.'
})
if len(player_name) > 10:
raise serializers.ValidationError({
'player_name': 'May not be more than 10 characters.'
})
# Return the validated values. This will be available as
# the `.validated_data` property.
return {
'score': int(score),
'player_name': player_name
}
def to_representation(self, instance):
return {
'score': instance.score,
'player_name': instance.player_name
}
def create(self, validated_data):
return HighScore.objects.create(**validated_data)
新しいベースクラスの作成
BaseSerializer
クラスは、特定のシリアル化スタイルを処理したり、代替のストレージバックエンドと統合したりするための新しい汎用シリアライザークラスを実装する場合にも役立ちます。
次のクラスは、任意の複合オブジェクトをプリミティブな表現に変換できる汎用シリアライザーの例です。
class ObjectSerializer(serializers.BaseSerializer):
"""
A read-only serializer that coerces arbitrary complex objects
into primitive representations.
"""
def to_representation(self, instance):
output = {}
for attribute_name in dir(instance):
attribute = getattr(instance, attribute_name)
if attribute_name.startswith('_'):
# Ignore private attributes.
pass
elif hasattr(attribute, '__call__'):
# Ignore methods and other callables.
pass
elif isinstance(attribute, (str, int, bool, float, type(None))):
# Primitive types can be passed through unmodified.
output[attribute_name] = attribute
elif isinstance(attribute, list):
# Recursively deal with items in lists.
output[attribute_name] = [
self.to_representation(item) for item in attribute
]
elif isinstance(attribute, dict):
# Recursively deal with items in dictionaries.
output[attribute_name] = {
str(key): self.to_representation(value)
for key, value in attribute.items()
}
else:
# Force anything else to its string representation.
output[attribute_name] = str(attribute)
return output
高度なシリアライザーの使用法
シリアライゼーションとデシリアライゼーションの動作のオーバーライド
シリアライザークラスのシリアル化またはデシリアル化の動作を変更する必要がある場合は、.to_representation()
または.to_internal_value()
メソッドをオーバーライドすることで変更できます。
これが役立つ可能性がある理由を次に示します...
- 新しいシリアライザーベースクラスの新しい動作の追加。
- 既存のクラスの動作を少し変更します。
- 大量のデータを返す頻繁にアクセスされるAPIエンドポイントのシリアル化パフォーマンスの向上。
これらのメソッドのシグネチャは次のとおりです。
to_representation(self, instance)
シリアル化が必要なオブジェクトインスタンスを受け取り、プリミティブな表現を返す必要があります。通常、これは組み込みのPythonデータ型の構造を返すことを意味します。処理できる正確な型は、API用に構成したレンダークラスによって異なります。
表現スタイルを変更するためにオーバーライドできます。例えば
def to_representation(self, instance):
"""Convert `username` to lowercase."""
ret = super().to_representation(instance)
ret['username'] = ret['username'].lower()
return ret
to_internal_value(self, data)
検証されていない受信データを入力として受け取り、serializer.validated_data
として利用可能になる検証済みのデータを返す必要があります。戻り値は、シリアライザークラスで.save()
が呼び出された場合、.create()
または.update()
メソッドにも渡されます。
検証に失敗した場合、メソッドはserializers.ValidationError(errors)
を発生させる必要があります。errors
引数は、フィールド名(またはsettings.NON_FIELD_ERRORS_KEY
)をエラーメッセージのリストにマッピングする辞書である必要があります。逆シリアル化の動作を変更する必要がなく、オブジェクトレベルの検証を提供したい場合は、代わりに.validate()
メソッドをオーバーライドすることをお勧めします。
このメソッドに渡されるdata
引数は、通常はrequest.data
の値となるため、提供するデータ型はAPIに構成したパーサークラスに依存します。
シリアライザーの継承
Djangoフォームと同様に、継承を通じてシリアライザーを拡張および再利用できます。これにより、親クラスに共通のフィールドまたはメソッドを宣言し、それを多数のシリアライザーで使用できます。例:
class MyBaseSerializer(Serializer):
my_field = serializers.CharField()
def validate_my_field(self, value):
...
class MySerializer(MyBaseSerializer):
...
DjangoのModel
クラスやModelForm
クラスと同様に、シリアライザーの内側のMeta
クラスは、親の内側のMeta
クラスから暗黙的に継承しません。Meta
クラスが親クラスから継承するようにする場合は、明示的に行う必要があります。例:
class AccountSerializer(MyBaseSerializer):
class Meta(MyBaseSerializer.Meta):
model = Account
通常、内部のMetaクラスで継承を使用するのではなく、すべてのオプションを明示的に宣言することをお勧めします。
さらに、シリアライザーの継承には次の注意点があります。
- 通常のPythonの名前解決ルールが適用されます。
Meta
内部クラスを宣言する複数のベースクラスがある場合、最初のもののみが使用されます。これは、子にMeta
が存在する場合はそれが使用され、それ以外の場合は最初の親のMeta
が使用されるということです。 -
サブクラスで名前を
None
に設定することにより、親クラスから継承されたField
を宣言的に削除できます。class MyBaseSerializer(ModelSerializer): my_field = serializers.CharField() class MySerializer(MyBaseSerializer): my_field = None
ただし、このテクニックは、親クラスによって宣言的に定義されたフィールドをオプトアウトする場合にのみ使用できます。
ModelSerializer
がデフォルトのフィールドを生成するのを防ぐことはできません。デフォルトのフィールドをオプトアウトするには、「含めるフィールドの指定」を参照してください。
フィールドの動的な変更
シリアライザーが初期化されると、シリアライザーに設定されたフィールドの辞書は、.fields
属性を使用してアクセスできます。この属性にアクセスして変更することで、シリアライザーを動的に変更できます。
fields
引数を直接変更することで、シリアライザーを宣言する時点ではなく、実行時にシリアライザーフィールドの引数を変更するなど、興味深いことができます。
例
たとえば、シリアライザーを初期化する時点で、シリアライザーで使用するフィールドを設定できるようにする場合は、次のようなシリアライザークラスを作成できます。
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super().__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields)
for field_name in existing - allowed:
self.fields.pop(field_name)
これにより、次のことが可能になります。
>>> class UserSerializer(DynamicFieldsModelSerializer):
>>> class Meta:
>>> model = User
>>> fields = ['id', 'username', 'email']
>>>
>>> print(UserSerializer(user))
{'id': 2, 'username': 'jonwatts', 'email': 'jon@example.com'}
>>>
>>> print(UserSerializer(user, fields=('id', 'email')))
{'id': 2, 'email': 'jon@example.com'}
デフォルトフィールドのカスタマイズ
REST framework 2には、ModelSerializer
クラスがデフォルトのフィールドセットを自動的に生成する方法を開発者がオーバーライドできるようにするAPIが用意されていました。
このAPIには、.get_field()
、.get_pk_field()
、その他のメソッドが含まれていました。
シリアライザーは3.0で根本的に再設計されたため、このAPIは存在しなくなりました。作成されるフィールドを変更することはできますが、ソースコードを参照する必要があり、行った変更がAPIのプライベート部分に対するものである場合は、変更される可能性があることに注意してください。
サードパーティパッケージ
次のサードパーティパッケージも利用可能です。
Django REST marshmallow
django-rest-marshmallowパッケージは、Pythonのmarshmallowライブラリを使用して、シリアライザーの代替実装を提供します。これはREST frameworkシリアライザーと同じAPIを公開し、一部のユースケースではドロップイン代替として使用できます。
Serpy
serpyパッケージは、速度を重視して構築されたシリアライザーの代替実装です。Serpyは、複雑なデータ型を単純なネイティブ型にシリアル化します。ネイティブ型は、JSONまたは必要なその他の形式に簡単に変換できます。
MongoengineModelSerializer
django-rest-framework-mongoengineパッケージは、Django REST frameworkのストレージレイヤーとしてMongoDBを使用することをサポートするMongoEngineModelSerializer
シリアライザークラスを提供します。
GeoFeatureModelSerializer
django-rest-framework-gisパッケージは、読み取りおよび書き込み操作の両方でGeoJSONをサポートするGeoFeatureModelSerializer
シリアライザークラスを提供します。
HStoreSerializer
django-rest-framework-hstoreパッケージは、django-hstore DictionaryField
モデルフィールドとそのschema-mode
機能をサポートするHStoreSerializer
を提供します。
Dynamic REST
dynamic-restパッケージは、ModelSerializerとModelViewSetインターフェースを拡張し、フィルタリング、ソート、およびシリアライザーで定義されたすべてのフィールドと関係を含める/除外するためのAPIクエリパラメーターを追加します。
Dynamic Fields Mixin
drf-dynamic-fieldsパッケージは、URLパラメーターで指定されたサブセットにシリアライザーごとのフィールドを動的に制限するためのミックスインを提供します。
DRF FlexFields
drf-flex-fieldsパッケージは、ModelSerializerとModelViewSetを拡張し、URLパラメーターとシリアライザークラスの定義の両方から、フィールドを動的に設定したり、プリミティブフィールドをネストされたモデルに展開したりするための一般的に使用される機能を提供します。
Serializer Extensions
django-rest-framework-serializer-extensionsパッケージは、ビュー/リクエストごとにフィールドを定義できるようにすることで、シリアライザーをDRY化するためのツールのコレクションを提供します。フィールドをホワイトリスト、ブラックリストに登録したり、子シリアライザーをオプションで展開したりできます。
HTML JSON Forms
html-json-formsパッケージは、(非アクティブな)HTML JSON Form仕様に基づいて、<form>
送信を処理するためのアルゴリズムとシリアライザーを提供します。シリアライザーは、HTML内の任意にネストされたJSON構造の処理を容易にします。たとえば、<input name="items[0][id]" value="5">
は、{"items": [{"id": "5"}]}
と解釈されます。
DRF-Base64
DRF-Base64は、base64エンコードされたファイルのアップロードを処理するフィールドとモデルシリアライザーのセットを提供します。
QueryFields
djangorestframework-queryfieldsを使用すると、APIクライアントは、含める/除外クエリパラメーターを介してレスポンスで送信されるフィールドを指定できます。
DRF Writable Nested
drf-writable-nestedパッケージは、ネストされた関連データを使用してモデルを作成/更新できる書き込み可能なネストされたモデルシリアライザーを提供します。
DRF Encrypt Content
drf-encrypt-contentパッケージは、ModelSerializerを通じてシリアル化されたデータを暗号化するのに役立ちます。また、データ暗号化に役立ついくつかのヘルパー関数も含まれています。