Джанго просмотров с вложенными сериализаторами - PullRequest
0 голосов
/ 08 ноября 2018

У меня следующая структура модели:

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


class Child1(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey(Parent)


class Child2(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey(Parent)

С сериализаторами:

class Child1Serializer(serializers.ModelSerializer):
    class Meta:
        model = Child1
        fields = (
            "name",
        )


class Child2Serializer(serializers.ModelSerializer):
    class Meta:
        model = Child2
        fields = (
            "name",
        )

class ParentSerializer(serializers.ModelSerializer):
    child1_ctx = Child1Serializer(many=False, required=False)
    child2_ctx = Child2Serializer(many=False, required=False)

    class Meta:
        model = Parent
        fields = (
            "name",
            "child1_ctx",
            "child2_ctx"
        )
        read_only_fields = ("name")

The ViewSet:

class ParentViewSet(GenericViewSet, RetrieveModelMixin, CreateModelMixin, UpdateModelMixin):
    serializer_class = ParentSerializer
    queryset = Parent.objects.all()

Однако при вызове ParentViewSet я получаю только поля для этой модели, а не комбинацию всех связанных с ней подмоделей!?

Возвращаемое значение:

{
 "name": "test"
}

1 Ответ

0 голосов
/ 08 ноября 2018

Вы можете изменить ваши модели примерно так:

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


class Child1(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey(Parent, related_name="children1")


class Child2(models.Model):
    name = models.CharField(max_length=100)
    parent = models.ForeignKey(Parent, related_name="children2")

Тогда в сериализаторе вы можете указать что-то вроде этого:

class ParentSerializer(serializers.ModelSerializer):
    child1 = serializers.SerializerMethodField()
    child2 = serializers.SerializerMethodField()

    class Meta:
        model = Parent
        fields = (
            "name",
            "child1",
            "child2",
        )
        read_only_fields = ("name")

    def get_child1(self, parent):
        return Child1Serializer(many=True, instance=parent.children1.all()).data

    def get_child2(self, parent):
        return Child2Serializer(many=True, instance=parent.children2.all()).data

В дочернем сериализаторе many=True, потому что несколько дочерних могут иметь иностранный ключ к родителю, поэтому для каждого родителя может быть более 1 дочернего. Если вы хотите вернуть только один дочерний элемент, вы можете сделать many=False, но затем убедиться, что вы передаете только одну дочернюю модель в экземпляре

...