Логика полей сериализатора

Я пытаюсь понять, как запустить некоторую логику для получения определенных объектов из моего сериализатора (или в другом месте).

У меня есть следующее:

class Parent(models.Model):
    name = models.CharField(max_length=255)


class Child(models.Model):
    name = models.CharField(max_length=255)
    parent = models.ForeignKey(
        Parent, related_name='children', on_delete=models.CASCADE)


class ChildSerializer(serializers.ModelSerializer):
    class Meta:
        model = Exercise
        fields = (
            'id',
            'name',
        )


class ParentSerializer(serializers.ModelSerializer):
    children = ChildSerializer()

    class Meta:
        model = Exercise
        fields = (
            'id',
            'name',
            'children',
        )


class ParentViewSet(viewsets.ModelViewSet):
    serializer_class = ParentSerializer
    queryset = Parent.objects.all()


class ChildViewSet(viewsets.ModelViewSet):
    serializer_class = ChildSerializer
    queryset = Child.objects.all()

Я хотел бы добавить в ответ parent поле: first_child, которое является первым дочерним по алфавиту name (в реальности эта логика будет немного сложнее, например, наибольшее значение суммы нескольких полей). Я также удалю поле children в пользу этого поля first_child, поскольку их количество будет слишком велико для отображения в строке таким образом.

Вы можете использовать метод to_representation

class ParentSerializer(serializers.ModelSerializer):
    children = ChildSerializer()

    def to_representation(self, instance):
        data = super().to_representation(instance=instance)
        first_child = instance.children.order_by("name").first()
        data["first_child"] = ChildSerializer(first_child, read_only=True).data if first_child else None
        return data

    class Meta:
        model = Parent # change model name
        fields = (
            'id',
            'name',
            'children',
        )

Или, используйте SerializerMethodField:

class ParentSerializer(serializers.ModelSerializer):
    children = ChildSerializer()
    first_child = serializers.SerializerMethodField()

    def get_first_child(self, instance):
        first_child = instance.children.order_by("name").first()
        if first_child:
             return ChildSerializer(first_child, read_only=True).data
        return None

    class Meta:
        model = Parent # Change model here
        fields = (
            'id',
            'name',
            'children',
            'first_child',
        )
Вернуться на верх