2015-12-19 4 views
6

mit detail_route Das ist mein Viewset:eine KeyError für 'request' in DRF Serializer empfangen, wenn in meinem Viewset

class PostViewSet(viewsets.ModelViewSet): 
    serializer_class = PostSerializer 
    permission_classes = (IsAuthenticated, IsOwnerDeleteOrReadOnly) 

    def get_queryset(self): 
     return Post.objects.filter(location=self.request.user.userextended.location) 

    def perform_create(self, serializer): 
     serializer.save(owner=self.request.user, location=self.request.user.userextended.location) 

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

    @detail_route(methods=['post'], permission_classes=[IsAuthenticated, IsFromLocation]) 
    def like(self, request, pk=None): 
     post = self.get_object() 
     post.usersVoted.add(request.user) 
     return Response(status=status.HTTP_204_NO_CONTENT) 

    @detail_route(methods=['get'], permission_classes=[IsAuthenticated, ValidPostPkInKwargs, IsFromPostLocation]) 
    def replies(self, request, pk=None): 
     post = self.get_object() 
     replies = post.postreply_set.all() 
     serializer = PostReplySerializer(replies, many=True) 
     return Response(serializer.data) 

Und das ist mein PostReplySerializer:

class PostReplySerializer(serializers.ModelSerializer): 
    owner = serializers.SlugRelatedField(slug_field='username', read_only=True) 
    voted = serializers.SerializerMethodField() 

    def get_voted(self, obj): 
     return self.context['request'].user in obj.usersVoted.all() 

    class Meta: 
     model = PostReply 
     fields = ('id', 'owner', 'post', 'voted', 'location') 

Die Fehlerpunkte auf der Linie

return self.context['request'].user in obj.usersVoted.all() 

und sagt:

KeyError at /URL/20/replies/ 
'request' 

Eine Idee, warum DRF sagt "Anfrage" ist ein Schlüsselfehler, obwohl (aus meiner Sicht) sollte es automatisch in self.context sein?

Beachten Sie, dass PostViewSet funktioniert perfekt für alle anderen Anfragen (wenn ich einen Post, eine Liste von Posts usw.). Es funktioniert einfach nicht für replies.

Antwort

4

Es ist nicht in self.context, weil Sie get_serializer_context überschrieben haben. request Objekt wird über diese Methode an Kontext gebunden. Fügen Sie einfach request: self.request in Ihrer Rückmeldung von get_serializer_context hinzu, die das Problem lösen würde. Sehen Sie sich die Standardimplementierung von get_serializer_context hier https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/generics.py um mehr zu verstehen. Hoffe, es hilft ..

EDIT Da Sie verschiedene Serializer (PostReplySerializer) in detail_route verwenden, müssen Sie Serializer Instanz wie serializer = PostReplySerializer(replies, many=True, context={'request': self.request})

+0

Seltsam erstellen. Selbst wenn ich ''request': self.request,' in der return-Anweisung, bekomme ich immer noch den gleichen Fehler. Könnte es etwas damit zu tun haben, dass der Serializer, den ich in meiner detail_route verwende, anders ist als der, den ich in meinem Viewset verwende? Edit: Auch wenn ich 'get_serializer_context()' vollständig aus meinem Viewset entferne und nicht überschreibe, bekomme ich aus irgendeinem Grund immer noch den gleichen Fehler. – user2719875

+1

ja .. Das liegt daran, dass Sie in detail_route einen anderen Serializer verwenden. Versuchen Sie, beim Erstellen der Serializer-Instanz 'context = {'request': self.request}' zu übergeben. wie 'serializer = PostReplySerializer (Antworten, viele = True, Kontext = {'request': self.request})'. Dies würde das Problem lösen. –

+0

Oh okay danke! Irgendeine Idee, warum die detail_route die Serializer-Kontexte nicht empfängt, obwohl sie Teil desselben Viewsets ist? Gibt es Unterlagen, die es erwähnen? Ich frage nur, damit ich verstehen kann, was genau los ist. Danke im Voraus! – user2719875

Verwandte Themen