How to get the current user object inside a Serializer method field in Django (while doing GET request)?

Issue

Below is my Serialzer method where I need the current user object to perform a logic,but it throws keyerror ‘request’
I have tried all the possible solution’s from stack over flow , but no luck
I am new to django
edit: I have posted the full code now , please check and knbldy help me in sorting this out

views.py

class Allview1(APIView,LimitOffsetPagination):
 permission_classes = (permissions.IsAuthenticated,)
 @swagger_auto_schema(
 query_serializer=PaginationSerializer,
 responses={status.HTTP_200_OK: []},
 operation_id="all_comments",
 )
 def get(self, request, *args, **kwargs):
 flag = kwargs['flag']
 pk = uuid.uuid4()
 start_time = dt.datetime.now()
 comment_id = request.GET.get('comment_id', '')
 #print(f" Request call for {__class__.__name__} {flag} | start_time : {start_time} | (Request_id : {pk}) ")
 logger.info(f" Request call for {__class__.__name__} {flag} | start_time : {start_time} | (Request_id : {pk}) ")


 response = {}
 today_max = dt.datetime.combine(dt.date.today(), dt.time.max)
 time_threshold = dt.datetime.now() - timedelta(days=1)
 threedays = dt.datetime.today() - timedelta(days=3)

 if flag == 'rec':
 recent_comments=redis_client.get("feeds:rec_comments")
 if recent_comments and int(request.GET.get('limit'))<=30:
 print("from cache")
 rec=pickle.loads(recent_comments)

 else:
 print("usual call")
 silenced_comments = StockUserComments.objects.filter(edit_type=EditTypeEnum.SILENCED_POST).values_list('id')
 private_users = list(ProfileSettings.objects.select_related('owner').filter(profile_public_discovery=False).values_list('owner__id', flat=True))

 rec = StockUserComments.objects.filter(Q(comment_text__length__gte=125) | Q(edit_type=EditTypeEnum.OUTLOOK)).exclude(user_id__in=private_users).exclude(id__in=silenced_comments).order_by("-date")

 cache_obj = redis_client.get("feeds:rec_comments")
 if not cache_obj:
 cache_obj = pickle.dumps(rec[:30])
 redis_client.set("feeds:rec_comments", cache_obj, ex=1800)

 results = self.paginate_queryset(rec, request, view=self)
 recent_comments = StockUserCommentsOutputSerializer1(results,many=True,context={'request':request})
 response["recently_discussed"] = recent_comments.data

 if flag == 'top':
 top_comments = redis_client.get("feeds:top_comments")
 if top_comments and int(request.GET.get('limit'))<=30:
 print("from cache")
 all = pickle.loads(top_comments)

 else:
 print("Usual call")
 silenced_comments = StockUserComments.objects.filter(edit_type=EditTypeEnum.SILENCED_POST).values_list('id')
 private_users = list(ProfileSettings.objects.select_related('owner').filter(profile_public_discovery=False).values_list('owner__id', flat=True))
 featured = StockUserComments.objects.filter(f_date__gte=time_threshold,edit_type=EditTypeEnum.FEATURED_POST).order_by("-f_date")

 qs = StockUserComments.objects.filter(date__gte=threedays).exclude(user_id__in=private_users).exclude(upvote__exact=0).exclude(Q(id__in=silenced_comments) | Q(id__in=featured)).order_by("-upvote")
 latest =StockUserComments.objects.filter(Q(comment_text__length__gte=125) | Q(edit_type=EditTypeEnum.OUTLOOK)).exclude(id__in=silenced_comments).exclude(id__in=qs).order_by("-date")
 featured = StockUserComments.objects.filter(f_date__gte=time_threshold,edit_type=EditTypeEnum.FEATURED_POST).order_by("-f_date")
 all =list(chain(featured,qs,latest))
 #print(all)
 cache_obj=redis_client.get("feeds:top_comments")
 if not cache_obj:
 cache_obj=pickle.dumps(all[:30])
 redis_client.set("feeds:top_comments", cache_obj,ex=1800)


 results = self.paginate_queryset(all, request, view=self)
 overall_comments = StockUserCommentsOutputSerializer1(results,many=True,context={'request':request})
 response["top_comments"] = overall_comments.data

 end_time = dt.datetime.now()
 #print(f" Response call for {__class__.__name__} {flag} | end_time : {end_time} | overall_time_taken : {end_time - start_time} | (Request_id : {pk}) ")
 logger.info(f" Response call for {__class__.__name__} {flag} | end_time : {end_time} | overall_time_taken : {end_time - start_time} | (Request_id : {pk}) ")

 return self.get_paginated_response(response)
 

serialzers.py

class StockUserCommentsOutputSerializer1(EnumChoiceModelSerializerMixin,serializers.ModelSerializer):
 user_detail = UserDetailSerializer(source='user',allow_null=True, required=False)
 replys = serializers.SerializerMethodField()
 ticker_logo = serializers.SerializerMethodField()
 tuser = TUserSerializer(many=True, allow_null=True, required=False)
 tsymbol = TSymbolSerializer(many=True, allow_null=True, required=False)
 company_name = serializers.SerializerMethodField()
 symbol_id=serializers.CharField(source='symbol')
 can_vote=serializers.SerializerMethodField()

 class Meta:
 model = StockUserComments
 fields = ['id', 'symbol_id','company_name', 'ticker_logo', 'comment_text', 'date', 'user_detail', 'replys', 'upvote', 'can_vote','parent','tuser','tsymbol','edit_type','outlook']

 def get_ticker_logo(self, obj):
        if obj.symbol:
            if obj.symbol.logo_url:
                return obj.symbol.logo_url
            else:
                return None
        else:
            return None


    def get_company_name(self, obj):
        if obj.symbol:
            if obj.symbol.name:
                return obj.symbol.name
            else:
                return None
        else:
            return None

    def get_replys(self, obj):
        queryset = StockUserComments.objects.filter(parent_id=obj.id).order_by('date')
        serializer = StockUserCommentsOutputSerializer1(queryset, many=True)
        return serializer.data

    def get_can_vote(self,obj):
        user = self.context['request'].user
        print(user)
        if obj.id and user:
            voter_data = CommentVotes.objects.filter(voter=user, comment=obj.id)
        if len(voter_data) > 0:
            return False
        else:
            return True

error

Traceback (most recent call last):
  File "E:\stocktalk-api-platform\venv\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
    response = get_response(request)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\django\views\generic\base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\views.py", line 476, in raise_uncaught_exception
    raise exc
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "E:\stocktalk-api-platform\apps\stock_dashboard\views.py", line 756, in get
    response["recently_discussed"] = recent_comments.data
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 760, in data
    ret = super().data
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 677, in to_representation
    return [
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 678, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 529, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\fields.py", line 1905, in to_representation
    return method(value)
  File "E:\stocktalk-api-platform\apps\stock_comments\serializers.py", line 178, in get_replys
    return serializer.data
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 760, in data
    ret = super().data
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 260, in data
    self._data = self.to_representation(self.instance)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 677, in to_representation
    return [
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 678, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\serializers.py", line 529, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "E:\stocktalk-api-platform\venv\lib\site-packages\rest_framework\fields.py", line 1905, in to_representation
    return method(value)
  File "E:\stocktalk-api-platform\apps\stock_comments\serializers.py", line 181, in get_can_vote
    user = self.context['request'].user
KeyError: 'request'
[30/Aug/2021 21:02:49] "GET /api/v1/dashboard/all_comments1/rec/?limit=10&offset=0 HTTP/1.1" 500 25528

Solution

You will have to directly pass request in context of the serializer as below.

SerializerClass(..., context={'request':request})

But if you use GenericAPIView, this behaviour is inherent and can access request directly in your serializer.

Add context in your serializer.

def get_replys(self, obj):
    queryset = StockUserComments.objects.filter(parent_id=obj.id).order_by('date')
    # Here
    serializer = StockUserCommentsOutputSerializer1(queryset, many=True, context=self.context)
    return serializer.data

Answered By – Ashin Shakya

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published