I'm using Django Rest Framework 3.3.2 with Django 1.9.1 I have 2 serializers and I use one of them inside the other one.
class VideoSerializer(serializers.ModelSerializer):
current_username = serializers.SerializerMethodField()
is_deletable = serializers.SerializerMethodField()
tagged_users = EachUserSerializer(many=True, read_only=True)
print current_username
comments = CommentSerializer(many=True, read_only=True, context={'current_username': current_username})
place_taken = PlaceLimitedSerializer()
owner_user = EachUserSerializer()
class Meta:
model = Video
fields = ('tagged_users', 'comments', 'place_taken', 'video_id', 'video_url', 'like_count', 'caption', 'date',
'category', 'owner_user', 'current_username', 'is_deletable', )
def get_current_username(self, obj):
self.current_username = self.context['request'].user.username
return self.context['request'].user.username
def get_is_deletable(self, obj):
return obj.is_deletable_by(self.current_username)
class CommentSerializer(serializers.ModelSerializer):
current_username = serializers.SerializerMethodField()
is_deletable = serializers.SerializerMethodField()
is_editable = serializers.SerializerMethodField()
def get_current_username(self, obj):
self.current_username = self.context['current_username']
return self.current_username
def get_is_deletable(self, obj):
return obj.is_deletable(self.current_username)
def get_is_editable(self, obj):
return obj.is_editable(self.current_username)
class Meta:
model = Comment
fields = ('comment', 'username', 'comment_id', 'date', 'current_username', 'is_editable', 'is_deletable',)
My question is that I need current user's username in serializers. I managed to do that in VideoSerializer by setting a context in view like this.
class get_video(APIView):
def get(self, request):
video_id = str(request.query_params.get('video_id'))
if Video.objects.all().filter(video_id=video_id).exists():
video = Video.objects.get(video_id=video_id)
serializer = VideoSerializer(video, context={"request": request})
return JsonResponse(serializer.data)
else:
return JsonResponse({"result": "no_video"})
In VideoSerializer, I tried to set context and I want to pass 'current_user' to the CommentSerializer but it gives this error.
Internal Server Error: /video/get_video/
Traceback (most recent call last):
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/views.py", line 466, in dispatch
response = self.handle_exception(exc)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/views.py", line 463, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/mcagataybarin/molocate-dev/molocate_eb/video/views.py", line 96, in get
return JsonResponse(serializer.data)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/serializers.py", line 503, in data
ret = super(Serializer, self).data
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/serializers.py", line 239, in data
self._data = self.to_representation(self.instance)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/serializers.py", line 472, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/serializers.py", line 614, in to_representation
self.child.to_representation(item) for item in iterable
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/serializers.py", line 472, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/Users/mcagataybarin/molocate-dev/env/lib/python2.7/site-packages/rest_framework/fields.py", line 1645, in to_representation
return method(value)
File "/Users/mcagataybarin/molocate-dev/molocate_eb/video/serializers.py", line 13, in get_current_username
self.current_username = self.context['current_username']
KeyError: 'current_username'
How can I fix that ? I checked the DRF documentation and also checked the stackoverflow but couldn't find the right answer. I'd appreciate if you help.
The context
is available for anything that is under the top serializer - i.e. applies to Serializers and Fields as well.
Therefore in the CommentSerializer you should have:
self.current_username = self.context['request'].user.username
After a lot of google search, I fixed the problem like this.
class VideoSerializer(serializers.ModelSerializer):
current_username = serializers.SerializerMethodField()
is_deletable = serializers.SerializerMethodField()
tagged_users = EachUserSerializer(many=True, read_only=True)
comments = serializers.SerializerMethodField()
place_taken = PlaceLimitedSerializer()
owner_user = EachUserSerializer()
class Meta:
model = Video
field = ('tagged_users', 'comments', 'place_taken', 'video_id', 'video_url', 'like_count', 'caption', 'date',
'category', 'owner_user', 'is_deletable', )
def get_comments(self, obj):
serializer_context = {'current_username': self.current_username}
serializer = CommentSerializer(obj.comments, many=True, read_only=True, context=serializer_context)
return serializer.data
def get_current_username(self, obj):
self.current_username = self.context['request'].user.username
return self.context['request'].user.username
def get_is_deletable(self, obj):
return obj.is_deletable_by(self.current_username)
class CommentSerializer(serializers.ModelSerializer):
current_username = serializers.SerializerMethodField()
is_deletable = serializers.SerializerMethodField()
is_editable = serializers.SerializerMethodField()
def get_current_username(self, obj):
self.current_username = self.context.get('current_username')
return self.context.get('current_username')
def get_is_deletable(self, obj):
return obj.is_deletable(self.current_username)
def get_is_editable(self, obj):
return obj.is_editable(self.current_username)
class Meta:
model = Comment
fields = ('comment', 'username', 'comment_id', 'date', 'current_username', 'is_editable', 'is_deletable',)
I serialized the nested serialization inside SerializerMethodField and I've sent the current_username that I extract from context to the nester serializer's context. After doing this problem solved and it works :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With