2016-05-17 4 views
7

Django REST Frameworkでは、args/kwargsをシリアライザに追加して、request.data経由ではなくurlパラメータまたはクッキーの値を使用して設定されたフィールドの値を設定するのはかなり標準的な作業です。例えば、私のコメントモデルのuserフィールドをrequest.userに設定する必要があります。これらの追加引数はコンテキストと呼ばれます。Django RESTフレームワーク:シリアライザのコンテキストの仕組みは?

StackOverflowのいくつかの質問(12)は、私がModelViewSetget_serializer_context()メソッドを上書きすることを提案しています。私はしたし、それは助けにはなりません。私は、何が間違っているのか理解しようとしましたが、ソースコードから、このコンテキストシステムがどのように一般的に動作するはずであるか分かりません。 (この問題に関するドキュメントもありません)

シリアライザがコンテキストを通常のリクエストデータに追加する場所は誰でも説明できますか?私は2つの場所を見つけ、そこから文脈の値を保存します。

  1. serializer.save()、検証データとkwargsからを混合する方法であって、それは通常(例えばModelMixinsによって)引数なしで呼び出されます。
  2. fields.__new__()は、argsとkwargsをキャッシュしますが、後で誰も読むことはありません。あなたは汎用ビューまたはビューセットを使用するたびに

答えて

7

、DRF(3.3.2)requestオブジェクト、view対象とシリアライザcontextからformatを追加します。あなたはserializer.contextを使ってアクセスすることができます。シリアライザではrequest.userと言うことができます。

get_serializer_class()が呼び出されたときに追加されます。その内部では、get_serializer_context()メソッドが呼び出され、これらのすべてのパラメータがコンテキストに追加されます。

参照用DRFソースコード:

class GenericAPIView(views.APIView): 
    """ 
    Base class for all other generic views. 
    """ 

    def get_serializer(self, *args, **kwargs): 
     """ 
     Return the serializer instance that should be used for validating and 
     deserializing input, and for serializing output. 
     """ 
     serializer_class = self.get_serializer_class() 
     kwargs['context'] = self.get_serializer_context() 
     return serializer_class(*args, **kwargs)  

    def get_serializer_context(self): 
     """ 
     Extra context provided to the serializer class. 
     """ 
     return { 
      'request': self.request, 
      'format': self.format_kwarg, 
      'view': self 
     } 
+0

それほど私は考えましたが、後で何が起こるのですか?私は見ることができません。シリアライザは、このコンテキストを使用してフィールドに値を設定します。 –

+0

通常の場合、コンテキストはシリアライザによって使用されません。シリアライザで 'request'オブジェクトにアクセスしたい場合、' self.context.get( 'request') 'を使います。また、シリアライザフィールドの 'to_representation'メソッドでは、' self.context'変数を使用して 'context'にアクセスできます。 –

+0

([docs](http://www.django-rest-framework.org/api-guide/serializers/#including-extra-context)から) 'context'を含むよくあるケースは、あなたがハイパーリンクされたリレーションを含むシリアライザ。シリアライザが現在のリクエストにアクセスして、完全修飾URLを適切に生成できるようにする必要があります。 –

0

request.data介しない設定項目の値を設定するが、URLパラメータまたはクッキーの値経由します。例えば、私のコメントモデルのユーザーフィールドをPOSTリクエスト時にrequest.userに等しくする必要があります。

これは私が私のModelViewSetで両方のケースを処理する方法である:

def perform_create(self, serializer): 

    # Get article id from url e.g. http://myhost/article/1/comments/ 
    # obviously assumes urls.py is setup right etc etc 
    article_pk = self.kwargs['article_pk'] 
    article = get_object_or_404(Article.objects.all(), pk=article_pk) 

    # Get user from request 
    serializer.save(author=self.request.user, article=article) 

は、残念ながら、ネストされたオブジェクトは、DRFのための標準ではありませんが、それはポイント以外にもあります。 :)

関連する問題