如何在DRF中将上下文从一个序列化器传递到另一个序列化器?

0 投票
1 回答
24 浏览
提问于 2025-04-14 18:17

我看到很多关于这个问题的重复讨论,特别是这个 关于Django REST框架中嵌套序列化器的上下文,但是没有一个对我有用。我尝试了很多讨论中提到的解决方案,特别是自定义序列化器、使用父类的 init() 方法,以及使用父类的 to_representation() 方法,但上下文就是没有从父类传递到子类。听说在更新的Django版本中应该是自动传递的,但对我来说并没有生效。(Django 5.0.2)

在我的例子中,我序列化一个帖子,而帖子的评论是通过调用评论序列化器来序列化的。对于每个被序列化的评论,我想检查用户是否已经对其投票,因此我创建了一个字段 user_vote。当我从父类打印请求时,它正常显示,但从子类打印时,请求是空的。

Serializers.py

class CommentSerializer(ModelSerializer):
    child_comment = serializers.SerializerMethodField()
    user_vote = serializers.SerializerMethodField()

    class Meta:
        model = Comment
        fields = '__all__'

    
    def get_user_vote(self, obj):
        # Get the current user from the request
        print(self.context, file=sys.stderr)
        user = self.context['request'].user

        # Check if a vote exists for the current user and comment
        try:
            vote = Vote.objects.get(user=user, comment=obj)
            return vote.value
        except Vote.DoesNotExist:
            return 0
    
class PostSerializerSingle(ModelSerializer):
    images = SheetMusicImageSerializer(many=True)
    comments = CommentSerializer(many=True)

    class Meta:
        model = Post
        fields = '__all__'

1 个回答

0

最后我自己想出了一个解决办法。显然,在某个时候,Django会自动把上下文传递给子序列化器,但从Django 5.0.2开始,这个功能就不再存在了。

代码:

class CommentSerializer(ModelSerializer):
    child_comment = serializers.SerializerMethodField()

    class Meta:
        model = Comment
        fields = '__all__'

    # example function
    def get_child_comment(self, obj):

        # you can access the context in the child function now
        print(self.context.get('request'))
        return serializer.data
    
        
    
class PostSerializerSingle(ModelSerializer):
    user_vote = serializers.SerializerMethodField()
    images = SheetMusicImageSerializer(many=True)
    comments = serializers.SerializerMethodField()

    class Meta:
        model = Post
        fields = '__all__'
    
    # pass in the context through here
    def get_comments(self, obj):
        comments = obj.comments.all()

        serializer = CommentSerializer(comments, many=True, context={'request': self.context.get('request') })
        return serializer.data

解决办法就是在父序列化器里设置一个字段,然后用一个自定义的函数把这个字段的值传给子序列化器,同时把上下文也传进去。我遇到麻烦的原因是,在父序列化器类里面无法访问上下文,因为类定义里没有self这个东西,我没意识到其实可以通过简单地创建一个自定义方法来解决这个问题。

撰写回答