[Django]-Pass request context to serializer from Viewset in Django Rest Framework

173👍

✅

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()

20👍

For Function based views you can pass request or user as follows:

serializer = ProductSerializer(context = {"request": request}, data=request.data)

Your Serializer may look like:

class ProductSerializer(serializers.ModelSerializer):
    class Meta:
        model = Product
        fields = ["id"]

    def create(self, validated_data):
        user = self.context["request"].user
        print(f"User is: {user}")

Feel free to inform if there is any better way to do this.

3👍

just use get_serializer() in your viewsets

def get_serializer(self, *args, **kwargs):
    """
    Return the serializer instance that should be used for validating and
    deserializing input, and for serializing output.
    """
    serializer_class = self.get_serializer_class()
    kwargs['context'] = self.get_serializer_context()
    return serializer_class(*args, **kwargs)

2👍

Return parent context in overrided function get_serializer_context will make it easy to access request and its data.

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

       def get_serializer_context(self):
       """
       pass request attribute to serializer
       """
           context = super(myModelViewSet, self).get_serializer_context()
           return context

This is very stable as every time we request viewset, it returns context as well.

1👍

the values for a serializer field depend on the identity of the currently logged in user

This is how I handle such cases in my ModelViewSet:

def perform_create(self, serializer):

    user = self.request.user
    if user.username == 'myuser':
        serializer.data['myfield'] = 'something'

    serializer.save()

1👍

Simply add this 2 line method in your class and you are good to go.

def get_serializer_context(self):
    return {'request': self.request}

1👍

since the posted answers had partial correctness, summarizing here in the interest of completeness.

  1. override get_serializer_context..AND
  2. use get_serializer in your views instead of manually calling the serializer

0👍

In my case, I could fix it by replacing the serializer definition

class MyListView(APIView):
    serializer_class = YourSerializerClass

    def get(self, request):
        queryset = self.get_queryset()
        serializer = self.serializer_class(queryset, many=True) #replace this
        return Response(serializer.data)

replace the serializer with

serializer = self.get_serializer(queryset, many=True)

Leave a comment