2015-12-19 14 views
6

To mój ViewSet:Odbieranie KeyError dla 'zamówienie' w DRF serializatora podczas korzystania detail_route w moim 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) 

A to moja 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') 

Punkty błędach do linii

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

i mówi:

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

Każdy pomysł, dla którego DRF mówi "prośba", jest kluczowym błędem, mimo że (z mojego zrozumienia) powinien on automatycznie być w self.context?

Pamiętaj, że PostViewSet działa idealnie dobrze dla wszystkich innych żądań (jeśli dostanę Post, otrzymam listę postów itp.). To po prostu nie działa dla replies.

Odpowiedz

4

To nie jest self.context, ponieważ nadpisałeś get_serializer_context. request obiekt jest dołączony do kontekstu tą metodą. Wystarczy dodać request: self.request w swoim oświadczeniu return z get_serializer_context, które rozwiąże problem. Spójrz na domyślną implementację get_serializer_context tutaj https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/generics.py, aby zrozumieć więcej. Nadzieję, że to pomaga ..

EDIT Ponieważ używasz innego serializatora (PostReplySerializer) w detail_route, trzeba stworzyć instancję serializer jak serializer = PostReplySerializer(replies, many=True, context={'request': self.request})

+0

dziwne. Nawet gdy dodaję ''request': self.request,' w instrukcji return, nadal otrzymuję ten sam błąd. czy to może mieć coś wspólnego z faktem, że serializator, którego używam w moim detail_route, jest inny niż ten, którego używam w moim widoku? Edycja: Nawet jeśli usunę "get_serializer_context()' całkowicie z mojego zestawu widoków i go nie zastąpię, nadal otrzymuję ten sam błąd z jakiegoś powodu. – user2719875

+1

tak .. To dlatego, że używasz innego serializera w detail_route. Spróbuj podać 'context = {'request': self.request}' podczas tworzenia instancji serializera. jak 'serializer = PostReplySerializer (replies, many = True, context = {'request': self.request})'. To rozwiązałoby problem. –

+0

Oh ok dzięki! Każdy pomysł, dlaczego element detail_route nie otrzymuje kontekstów serializera, mimo że jest częścią tego samego zestawu widoków? Czy jest jakaś dokumentacja, która wspomina o tym? Pytam tylko, czy mogę zrozumieć, co dokładnie się dzieje. Z góry dziękuję! – user2719875