【问题标题】:Current User inside nested serializer嵌套序列化程序中的当前用户
【发布时间】:2016-01-30 23:21:48
【问题描述】:

我正在使用 Django Rest Framework 3.3.2 和 Django 1.9.1 我有 2 个序列化程序,我在另一个内部使用其中一个。

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',)

我的问题是我需要在序列化程序中使用当前用户的用户名。我设法通过在这样的视图中设置上下文来在 VideoSerializer 中做到这一点。

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"})

在 VideoSerializer 中,我尝试设置上下文,我想将“current_user”传递给 CommentSerializer,但它给出了这个错误。

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'

我该如何解决?我检查了 DRF 文档并检查了 stackoverflow,但找不到正确的答案。如果您能提供帮助,我将不胜感激。

【问题讨论】:

    标签: django django-rest-framework serialization


    【解决方案1】:

    context 可用于顶级序列化程序下的任何内容 - 即也适用于序列化程序和字段。 因此在 CommentSerializer 中你应该有:

    self.current_username = self.context['request'].user.username
    

    【讨论】:

      【解决方案2】:

      经过大量谷歌搜索后,我解决了这个问题。

      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',)
      

      我在 SerializerMethodField 中对嵌套序列化进行了序列化,并将从上下文中提取的 current_username 发送到嵌套序列化器的上下文。解决这个问题后,它可以工作了:)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多