Search code examples
djangodjango-rest-frameworkserialization

Pass request context to serializer from Viewset in Django Rest Framework


I have a case where the values for a serializer field depend on the identity of the currently logged in user. I have seen how to add the user to the context when initializing a serializer, but I am not sure how to do this when using a ViewSet, as you only supply the serializer class and not the actual serializer instance.

Basically I would like to know how to go from:

class myModelViewSet(ModelViewSet):
   queryset = myModel.objects.all()
   permission_classes = [DjangoModelPermissions]
   serializer_class = myModelSerializer

to:

class myModelSerializer(serializers.ModelSerializer):
    uploaded_by = serializers.SerializerMethodField()
    special_field = serializers.SerializerMethodField()

    class Meta:
        model = myModel

    def get_special_field(self, obj):
        if self.context['request'].user.has_perm('something.add_something'):
           return something

Sorry if it wasn't clear, from the DOCs: Adding Extra Context Which says to do

serializer = AccountSerializer(account, context={'request': request})
serializer.data

But I am not sure how to do that automatically from the viewset, as I only can change the serializer class, and not the serializer instance itself.


Solution

  • GenericViewSet has the get_serializer_context method which will let you update context:

    class MyModelViewSet(ModelViewSet):
        queryset = MyModel.objects.all()
        permission_classes = [DjangoModelPermissions]
        serializer_class = MyModelSerializer
    
        def get_serializer_context(self):
            context = super().get_serializer_context()
            context.update({"request": self.request})
            return context
    

    For Python 2.7, use context = super(MyModelViewSet, self).get_serializer_context()