Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receiving a KeyError for 'request' in DRF serializer when using detail_route in my ViewSet

This is my 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)

And this is my 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')

The error points to the line

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

and says:

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

Any idea why DRF says 'request' is a key error even though (from my understanding) it should be automatically in self.context?

Note that PostViewSet works perfectly fine for all other requests (if I get a Post, get a list of posts etc.). It just doesn't work for replies.

like image 787
SilentDev Avatar asked Dec 19 '15 02:12

SilentDev


1 Answers

It's not in self.context because you have overridden get_serializer_context. request object is attached to context via this method. Just add request: self.request in your return statement of get_serializer_context that would solve the problem. Take a look at default implementation of get_serializer_context here https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/generics.py to understand more. Hope it helps..

EDIT Since you are using different serializer(PostReplySerializer) in detail_route, you need to create serializer instance like serializer = PostReplySerializer(replies, many=True, context={'request': self.request})

like image 107
Kaviraj Kanagaraj Avatar answered Nov 14 '22 02:11

Kaviraj Kanagaraj