2013-01-21 17 views
11

問題ジャンゴREST Frameworkと一般的な関係

私は、次の標準的な一般的な外部キーフィールドを持つモデルがあります:

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つの関連する状況では正常に動作しません。

  1. 私はHyperlinkedRelatedFieldを使用したいと思います。このフィールドにはview_name引数が必要です。ビュー名は関連するモデルによって異なるため、宣言できません。私はSerializerMethodFieldを使ってこれを解決し、実行時にHyperlinkedIdentityFieldをインスタンス化し、そのfield_to_nativeメソッドを返しました(以下のスニペットを参照)。これはあまりエレガントではありません。
  2. 私はevent_object = SoAndSoSerializer(source='event_object')と言って、関連するオブジェクトを直接シリアル化にネストしたいと思います。私が見ることができる唯一の解決策は、私が定義した正しいモデルを持っているかどうかを確認してから、それを使用するたびに歩くことです。繰り返しますが、これはあまりエレガントではありません。

質問

はHyperlinkRelatedFieldは、一般的な関係を越えて動作することを意図しているのですか?私は間違いをしていますか? *Serializer私は行方不明だと右のピッキングに明らかな解決策はありますか?私に

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) 
+1

ソースがフィールド名と異なる場合、フィールドの 'source'引数を使用するだけでよいことに注意してください。 'event_object'の場合は削除できます。 –

答えて

8

あなたの右、RESTフレームワークは、これらのユースケースをサポートしていない、とその明白ではない何を:

コードスニペット

上の箇条書き1で述べた無粋ソリューションもしそうなら、デザインは見えます。おそらく、私は非常に熱心だとは思わないモデル - >ビュー(ハイパーリンクの場合)とモデル - >シリアライザ(ネストされたケースの場合)の暗黙のレジストリが必要になります。

ManyRelatedFieldをサブクラス化して、カスタムフィールドタイプを作成し、to_native(self, obj)をオーバーライドして、セット内の各オブジェクトを必要な方法でシリアル化するのが最も簡単な方法です。

+0

Tomの健全性チェックに感謝します。私は「正しい」答え(貧弱な形)を持った質問をしなかったが、あなたは頭の中で多かれ少なかれ釘を打ったと思う。乾杯。 –

関連する問題