2016-06-21 6 views
4

私は2つのモデル(LikeとNews)を持っています。私はdjango-rest-frameworkを使ってWeb APIを作成しています。django rest framework - 要求コンテキストキーエラー

class Like(models.Model): 
    user = models.ForeignKey(User) 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = GenericForeignKey('content_type', 'object_id') 

class News(models.Model): 
    user = models.ForeignKey(User) 
    title = models.CharField(max_length=150) 
    ... 
    likes = GenericRelation(Like) 

オブジェクトようはニュースオブジェクトを気に入っ誰保存するために、独自のユーザー・フィールドがあります。特定のユーザーがNewsオブジェクトのいずれかのものに存在するかどうかを確認するために、私はSerializerMethodFieldからrequest.userを取得しています。

class NewsSerializer(serializers.HyperlinkedModelSerializer): 
    user = UserSerializer() 
    likes_count = serializers.IntegerField(source='likes.count', read_only=True) 
    user_in_likes = serializers.SerializerMethodField() 

    class Meta: 
     model = News 
     fields = ('user', 'title', 'body', 'article_image', 'pub_date', 'likes_count', 'user_in_likes') 

    def get_user_in_likes(self, obj): 
     user = self.context['request'].user 
     what = obj.likes.filter(user=user).exists() 
     return what 

私は/ニュース/ URLを行くとき、私は、各ニュースのオブジェクトのための真/偽にuser_in_likesを含むJSONオブジェクトを取得します。

しかし、私はNewsSerializer classおよび他の同様のシリアライザをインポート別のモデルのための別のserialzerあります

KeyError at /activities/

'request'

:私はエラーを取得しています活動のオブジェクトを取得するには、今、私は/activities/を訪問する場合

class ActivityObjectRelatedField(serializers.RelatedField): 
    def to_representation(self, value): 
     if isinstance(value, User): 
      serializer = UserSerializer(value) 
     elif isinstance(value, Job): 
      serializer = JobSerializer(value) 
     elif isinstance(value, News): 
      serializer = NewsSerializer(value) 
     elif isinstance(value, Tender): 
      serializer = TenderSerializer(value) 
     else: 
      raise Exception('Unexpected type of tagged object') 
     return serializer.data  

class ActivitySerializer(serializers.HyperlinkedModelSerializer): 
    actor = ActivityObjectRelatedField(read_only=True) 
    target = ActivityObjectRelatedField(read_only=True) 

    class Meta: 
     model = Activity 
     fields = ('url', 'actor', 'verb', 'target', 'pub_date') 

そして、NewsSerializeクラスのSerializerMethodの行を指しています(self.context['request'].userが使用されています)。私は/news/のURLを参照してください場合

Exception Location: /vagrant/myproject/news/serializers.py in get_user_in_likes, line 25

ここでも、すべてが正常であると私はニュースのオブジェクトを取得します。私はここで何が欠けていますか? ActivitiesSerializer classrequestが認識されないのはなぜですか?この問題を解決するのを手伝ってください。ありがとうございました。

答えて

5

to_representation()方法でNewsSerializerクラスまたは他の同様のシリアライザをインスタンス化するときにコンテキストでrequestを渡していないため、このエラーを取得しています。

to_representation()メソッドで、特定のシリアライザクラスを手動でインスタンス化しています。そのため、インスタンス化後、その特定のシリアライザはActivitySerializercontextへのアクセス権を持たないため、エラーが発生します。

することはできpassto_representation()方法で関連するシリアライザのインス​​タンス化ActivitySerializerさんcontext

class ActivityObjectRelatedField(serializers.RelatedField): 
    def to_representation(self, value): 
     if isinstance(value, User): 
      serializer = UserSerializer(value, context=self.context) # pass context 
     elif isinstance(value, Job): 
      serializer = JobSerializer(value, context=self.context) # pass context 
     elif isinstance(value, News): 
      serializer = NewsSerializer(value, context=self.context) # pass context 
     elif isinstance(value, Tender): 
      serializer = TenderSerializer(value, context=self.context) # pass context 
     else: 
      raise Exception('Unexpected type of tagged object') 
     return serializer.data  
+0

ありがとうございました! – Aamu

+0

とても役に立ちました – po5i

2

/activities/の表示で辞書にNewsSerializerというご要望があると思われます。

おそらくDjango REST Frameworkが提供するクラスベースのビューを使用して、この辞書を入力して(get_serializer_context() methodを参照)、それをSerializerインスタンスに渡します。そのため、シリアライザで自動的に利用できるのは/news/ビューです。

/activities/ビューでは、コンテキストはActivitySerializerに渡され、そこから(自動的に)伝播されません。そのため、NewsSerializerのコンテキスト辞書にはrequestというキーがありません。リクエストオブジェクトをNewsSerializerインスタンスに渡す必要があります。シリアライザに余分なコンテキストを渡すには、インスタンス化するときにcontextパラメータに辞書を含むパラメータを追加します(DRF documentationを参照)。

関連する問題