Django rest framework - использование SerializerMethodField с ModelSerializer
У меня есть следующие модели.
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)
Я хочу написать сериализатор, который будет возвращать список предметов. Каждый предмет имеет поле term, которое содержит None или один объект, в зависимости от 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')
Проблема заключается в том, что при condition == True
ViewSet возвращает неверные данные. Все поля внутри термина имеют значение по умолчанию.
Он работает нормально, если я пишу SubjectSerializer
следующим образом:
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')
Но случай, когда condition == False
не работает.
Попробуйте передать сериализатору экземпляр и контекст. Например, так:
def get_term(self, instance):
if self.context['condition']:
return TermSerializer(many=False, source='term_set', instance=instance, context=self.context).data
return None