Django rest framework инвертирует сериализаторы

В Django, у меня в models.py модели определены следующим образом :

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

class foo2(models.Model):
   name = models.CharField(max_length=100)
   ....
   foo1 = models.ForeignKey(foo1, on_delete=models.SET_NULL, null=True)
class foo3(models.Model):
   name = models.CharField(max_length=100)
   ....
   foo2 = models.ForeignKey(foo2, on_delete=models.SET_NULL, null=True)
class foo4(models.Model):
   name = models.CharField(max_length=100)
   ....
   foo3 = models.ForeignKey(foo3, on_delete=models.SET_NULL, null=True)

....

и то, что я ожидаю получить, это формат json, подобный этому :

[
  {
    "id": 1,
    "name": "test1",
    "foo2": {
        "id": 1,
        "name": "test1",
        "foo3": {
              "id": 1,
              "name": "test1",
              "foo3": { 
                 ...   
 }
},
....
]

Что я пробовал до сих пор, и это дает мне результат, противоположный тому, что я хочу, вот мой serlialize.py :

class NestedFoo1Serializer(serializers.ModelSerializer):
    class Meta:
        model = Company
        fields = '__all__'

class Nestedfoo2Serializer(serializers.ModelSerializer):
    foo1= NestedFoo1Serializer(read_only=True)
    class Meta:
        model = Facility
        fields = '__all__'

результат (противоположный тому, что я хочу):

[
  {
    "id": 1,
    "name": "test1",
    "foo4": {
        "id": 1,
        "name": "test1",
        "foo3": {
              "id": 1,
              "name": "test1",
              "foo2": { 
                 ...   
 }
},
....
]

и вот мой view.py :


class TreeView(generics.ListAPIView):
    serializer_class = NestedFoo4Serializer
    queryset = foo4.objects.all()

Хочу узнать, как инвертировать результат

Проблема может быть в ваших отношениях, а не в сериализаторах. Внешние ключи - это отношения "один ко многим", что для моделей вашего примера означает:

foo2 может иметь только один назначенный объект foo1, но многие объекты foo2 могут иметь один и тот же назначенный объект foo1. То же самое происходит между foo2 и foo3, foo3 и foo4 и т.д...

Если это то, что вы хотите, то API можно структурировать следующим образом:

[
  {
    "id": 1,
    "name": "test1",
    "foo2": [
      {
        "id": 1,
        "name": "test1",
        "foo3": [
          {
            "id": 1,
            "name": "test1",
            "foo3": [
              ...   
            ],
          },
          {...}
        ]
      },
      {...}
    ]
  },
....
]

Просто задайте связанное имя для каждого из отношений (или используйте имя по умолчанию, которое будет "слизанным" именем модели, где определено отношение, с добавлением _set в конце):

class foo2(models.Model):
   name = models.CharField(max_length=100)
   ....
   foo1 = models.ForeignKey(foo1, on_delete=models.SET_NULL, null=True, related_name="foo2s")

И используйте его в своих сериализаторах с этим связанным именем и many=True:

class foo1Serializer(serializers.ModelSerializer):
    foo2s = NestedFoo2Serializer(read_only=True, many=True)
    class Meta:
        model = foo1
        fields = '__all__'

Если вы хотите иметь точную структуру API, как вы предложили в своем вопросе, вы должны либо изменить отношения, так что отношение от foo1 к foo2 определяется в foo1, либо использовать OneToOneField вместо этого, что ограничит каждую foo2 модель уникальной foo1 моделью, назначенной ей.

Вернуться на верх