コンテンツタイプを格納する "content_type"フィールドと、オブジェクトIDを格納する "object_id"フィールドを使用する汎用外部キーを使用するモデルがあります。このモデルはCRUD APIで操作する必要があり、DRFを使用しています。私はモデルのシリアライザを持っていますが、少し問題があります。私はちょうどこのDRFでGenericForeignKeyをシリアル化する方法は?
class MySerializer(ModelSerializer): class Meta: fields = ('name', 'state', 'content_type', 'object_id')
のようなフィールドのリストにCONTENT_TYPEを追加した場合、シリアライザは、ContentTypeをモデルインスタンスのIDにJSON表現を設定します。 APIのユーザーはこれらのIDを認識しないため、さらに別のAPIを使用してContentTypeモデルを公開したくありません。 APIユーザーはリンクしたいオブジェクトの種類を知っているので、コンテンツタイプ名を送信できます。そこで、私はこのようなシリアライザを定義しました。
モデルをシリアライズするだけで問題ありません。一般的な関係を使用してUserインスタンスをリンクすると、{'name': 'test', 'state': 'NY', 'content_type': 'user', 'object_id': 123}
のようなものが得られます。しかし、JSON構造体でPUTまたはPOSTリクエストを送信すると、DRFはこれを{'name': 'test', 'state': 'NY', 'content_type': {'name': {'name': 'user'}}, 'object_id': 123}
のようなものに変換します。私は何かを書くことができる
def create(self, validated_data): ct_model = validated_data['content_type']['name']['name'] validated_data['content_type'] = ContentType.objects.get(model=ct_model) return MyModel.objects.create(**validated_data)
しかし、それは任意かつ壊れやすいようです。この状況に対処する正しい方法は何ですか?
更新#1:瞬間のために、私は(to_internal_valueをオーバーライドすることによって、問題を解決している)このコードの
def to_internal_value(self, data): content_type = data.get('content_type', None) validated_data = super().to_internal_value(data) try: validated_data['content_type'] = ContentType.objects.get(model=content_type) except ContentType.DoesNotExist: raise serializers.ValidationError("invalid content type %s" % content_type) return validated_data
表示するようにしなければならないために醜いハックのようなもののように思えます関連するオブジェクト。
ドキュメントhttp://www.django-rest-framework.org/api-guide/relations/#generic-relationshipsから解決策を試しましたか? – mateuszb
解決策はカスタム関連のフィールドクラスを定義することにあるようです。私はそれを調べるだろうが、それは畳み込まれているようだ。 –
あなた自身の質問に答えた場合は、それを回答として投稿し、更新として投稿しないでください。 –