問題
次の標準的な一般的な外部キーフィールドを持つモデルがあります。
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
event_object = generic.GenericForeignKey('content_type', 'object_id')
RESTフレームワークのドキュメントによると、これを正しくシリアル化するために次のことができます。
class WhateverSerializer(serializers.ModelSerializer):
event_object = serializers.RelatedField(source='event_object')
これは正常に機能しますが、他の2つの関連する状況では、動作させることができません。
- 使いたい
HyperlinkedRelatedField
です。このフィールドにはview_name引数が必要です。これは、ビュー名が関連するモデルによって異なるため、宣言できません。SerializerMethodField
を使用して、実行時にインスタンス化し、HyperlinkedIdentityField
そのメソッドを返すことでこれを解決しましたfield_to_native
(以下のスニペットを参照)。これはあまりエレガントではありません。 - と言って、関連するオブジェクトをシリアル化に直接ネストしたいと思います
event_object = SoAndSoSerializer(source='event_object')
。私が見ることができる唯一の解決策は、*Serializer
私が定義したすべてを歩き、正しいモデルを持っているものを確認し、それを使用することです。繰り返しますが、これはあまりエレガントではありません。
質問
HyperlinkRelatedFieldは、一般的な関係全体で機能することを目的としていますか?私はただ間違えているのですか?*Serializer
私が欠けている権利を選ぶための明白な解決策はありますか?
コードスニペット
上記の箇条書き1で述べたエレガントでない解決策:
class WhateverSerializer(DefaultSerializer):
event_object_url = serializers.SerializerMethodField('get_related_object_url')
# ...
def get_related_object_url(self, obj):
obj = obj.event_object
default_view_name = '%(model_name)s-detail'
format_kwargs = {
'app_label': obj._meta.app_label,
'model_name': obj._meta.object_name.lower()
}
view_name = default_view_name % format_kwargs
s = serializers.HyperlinkedIdentityField(source=obj, view_name=view_name)
s.initialize(self, None)
return s.field_to_native(obj, None)