2

I have the following models.

models.py

class Language(models.Model):
    name = models.CharField(max_length=255, unique=True)

class Subject(models.Model):
    name = models.CharField(max_length=255, unique=True)

class Term(models.Model):
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
    language = models.ForeignKey(Language, on_delete=models.CASCADE)
    name = models.CharField(max_length=255)
    definition = models.TextField()
    image = models.ImageField(default='', blank=True)

I want to write a Serializer that will return a list of subjects. Each subject has a term field, which contains None or a single object, depending on the condition.

serializers.py

class TermSerializer(serializers.ModelSerializer):
    language = serializers.CharField(source='language.name')

    def to_representation(self, data):
        data = data.get(language=self.context['language'])
        return super(TermSerializer, self).to_representation(data)

    class Meta:
        model = Term
        fields = ('id', 'language', 'name', 'definition', 'image')

class FilteredSubjectSerializer(serializers.ListSerializer):
    def to_representation(self, data):
        if self.context['condition']:
            terms = Term.objects.filter(language=self.context['language'])
            data = data.filter(term__in=terms)
        return super(FilteredSubjectSerializer, self).to_representation(data)

class SubjectSerializer(serializers.ModelSerializer):
    term = serializers.SerializerMethodField()

    def get_term(self, term):
        if self.context['condition']:
            return TermSerializer(many=False, source='term_set').data
        return None

    class Meta:
        model = Term
        list_serializer_class = FilteredSubjectSerializer
        fields = ('id', 'name', 'definition', 'image', 'term')

The problem is that when condition == True, the ViewSet returns incorrect data. All fields inside term have a default value.

It works fine if I write SubjectSerializer like this:

class SubjectSerializer(serializers.ModelSerializer):
    term = serializers.TermSerializer(many=False, source='term_set')

    class Meta:
        model = Term
        list_serializer_class = FilteredSubjectSerializer
        fields = ('id', 'name', 'definition', 'image', 'term')

But the case when condition == False doesn't work.

1 Answer 1

2

Try passing the serializer the instance and the context. Like this:

    def get_term(self, instance):
        if self.context['condition']:
            return TermSerializer(many=False, source='term_set', instance=instance, context=self.context).data
        return None
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much. It worked when I passed context and instance=instance.term_set.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.