Reputation: 69
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
Upvotes: 0
Views: 2158
Reputation: 696
Add the __init__
method to your serializer so as to make context a class variable. Then you can access the context passed as self.context
in the serializer methods. Try adding the following lines to serialzier class
def __init__(self, *args, **kwargs):
self.context = kwargs.get('context', None)
super(AssessmentListSerializer, self).__init__(*args, **kwargs)
you should still add checks to your methods hasattr(context, 'request') to avoid any 500 errors.
Upvotes: 1
Reputation: 776
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
Upvotes: 1
Reputation: 113
There's many ways to pass context to nested serializer. If you use for many instances easiest is to wrap your nested serializer(CommentsOutputSerializer1 with ListField). It will pass context of main serializer to nested by default.
https://stackoverflow.com/a/40260330/11354529
Upvotes: 2