22
class MyModelSerializer(serializers.ModelSerializer):
    field1 = serializers.CharField()
    field2 = serializers.SerializerMethodField('get_awesome_user')

    def get_current_user(self):
        request = self.context.get("request")
        if request and hasattr(request, "user"):
            return request.user
        return None

   def get_awesome_user(self, obj):
       user = self.get_current_user()
       ## use this user object, do some stuff and return the value
       return ...

My api(which uses authentication_classes and permission_classes) is using this serializer and the get_current_user function always returns None. when I debug it, I found that self.context is empty dictionary, i.e {}. to be double sure I also printed self.context.keys(), still it's empty list.

I followed this thread.

Get current user in Model Serializer

PS: I'm using djangorestframework==3.3.3, Django==1.9.1

EDIT: adding viewset code

class MyModelViewSet(viewsets.ModelViewSet):

    authentication_classes = (SessionAuthentication, BasicAuthentication, TokenAuthentication)
    permission_classes = (IsAuthenticated,)

    def list(self, *args, **kwargs):
         queryset = MyModel.objects.all()
         page = self.paginate_queryset(queryset)
         if page is not None:
             serializer = MyModelSerializer(page, many=True)
             return self.get_paginated_response(serializer.data)

         serializer = MyModelSerializer(queryset, many=True)
         return Response(serializer.data)
Community
  • 1
  • 1
Wendy
  • 1,523
  • 3
  • 12
  • 16
  • Usually, self.context is filled by `generics.py:GenericApiView.get_serializer_context()` function, which is called by `generics.py:GenericApiView.get_serializer()`, which in turn is called in the beginning of `viewset.list()/detail()/create()/delete()/update()` in `mixins.py`. Can you provide your ViewSet code, cause it is required to understand what you're trying to do? – Boris Burkov Jul 09 '16 at 12:17
  • @Bob : added viewset code in question details, plz have a look. – Wendy Jul 09 '16 at 12:39
  • Sorry for delay. Wendy, `#some stuff` doesn't explain much. How do you create serializer in your viewset's `list()` method? You should call `serializer = self.get_serializer(data=request.data)` to get your serializer context filled automatically, but I have a feeling that you're just creating it manually, like, `serializer = MyModelSerializer(instance)`. You should either call `get_serializer()`, or pass extra context argument to serializer constructor: `serializer = MyModelSerializer(instance, context={'request': request, ...})`. – Boris Burkov Jul 09 '16 at 13:28
  • @bob you should write that as an answer which I think is the correct one :) – Linovia Jul 09 '16 at 18:02
  • @Linovia I had a good teacher ;) Besides, I'm working on DRF-Mongoengine now, which is built on top of DRF. It is all swarming with bugs yet, so it's like 1) write a new endpoint - 2) see, what's failed - 3) write unit-test - 4) introduce bugfix. Nonetheless, I managed to get our REST Api up and running and it is so much more convenient to use mongoengine's EmbeddedDocuments for deeply nested JSONs than RDBMS relations or JSONFields with custom validation. It's working for us now and if something goes wrong, I know how to fix it and fix it. Cheers! – Boris Burkov Jul 09 '16 at 18:25
  • @bob grats and cheers :) – Linovia Jul 09 '16 at 20:29

1 Answers1

68

How do you create serializer in your viewset's list() method? You should call

serializer = self.get_serializer(data=request.data)

to get your serializer context filled automatically as it is done in default implementation of this method in DRF mixins., but I have a feeling that you're just creating it manually, like this:

serializer = MyModelSerializer(instance)

So, to fix this, you should either call get_serializer(), or pass extra context argument to serializer constructor:

serializer = MyModelSerializer(instance, context={'request': request, ...})
Boris Burkov
  • 13,420
  • 17
  • 74
  • 109
  • @Boris Burkov could you help me look into this please. It is a similar question but the solution here doesnt work for me. https://stackoverflow.com/questions/62039305/how-to-pass-extra-context-to-django-rest-framework-serializers. Thanks – banky May 27 '20 at 21:48