How can I pass context from one serializer to another in DRF [2024]?

I have seen many duplicate threads on this, most notably this context in nested serializers django rest framework, but none have worked for me. I have tried most solutions I see in every thread most notably CustomSerializers, using parents init(), and using parents to_representation(), but the context never passes from parent to child. Apparently it is supposed to pass automatically as of the newer django versions but it doesnt for me. (Django 5.0.2)

In my example I serialize a post which's comments are serialized by calling the comment serializer. For every comment being serialized, I want to check if the user has voted on it yet by creating a field user_vote. When I print the request from the parent it prints normally, however from the child it request is empty.

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__'

In the end I came up with a solution by myself. Apparently Django at some point automatically passed the context to children serializers but that is no longer the case as of Django 5.0.2.

code:

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

The solution is just by setting a field in the parent serializer, then using a custom function to set its value to the child serializer while passing the context in. The reason I had trouble was that the context wasnt accessible inside of the parent serializer class as there is no self inside of class definitions, and I didnt realize this could be circumvented through simply making a custom method.

Back to Top