Рекурсивная сериализация Django

#python #django #serialization #django-rest-framework

#python #django #сериализация #django-rest-framework

Вопрос:

Допустим, у меня есть такие модели:

 class A(models.Model):
    ...some fields here

class B(models.Model):
    ...some fields here
    a = models.ForeignKey(A, on_delete=CASCADE)

class C(models.Model):
    ...some fields here
    b = models.ForeignKey(B, on_delete=CASCADE)

...
  

И я хочу, чтобы моя конечная точка API возвращала что-то вроде этого

 {
  ...some fields here
  b: [
  {
    ...some field here
    c: [{...}, {...} ...]
  },
  {
    ...some field here
    c: [{...}, {...} ...]
  }
  ...
  ]
}
  

Я знаю, что могу сделать что-то подобное:

 class Bserializer(serializers.ModelSerializer):
  c = Cserializer(source="c_set", many=True, read_only=True,)

  class Meta:
      model = B
      fields = [...some fields, "c"]

class Aserializer(serializers.ModelSerializer):
  b = Bserializer(source="b_set", many=True, read_only=True,)

  class Meta:
      model = A
      fields = [...some fields, "b"]
  

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

Ответ №1:

Вы можете указать depth значение в Meta классе serializer, однако это не сработает, если вы хотите настроить какую-либо часть вложенных данных, поскольку это автоматически создаст сериализаторы модели (со всеми полями) для вложенных отношений. Проверьте документы здесь

 class Aserializer(serializers.ModelSerializer):

  class Meta:
      model = A
      fields = [...some fields, "b"]
      depth = 2
  

Суть в том, что если вы не выполняете никаких настроек вложенных сериализаторов, используйте его, в противном случае используйте пользовательские сериализаторы для каждого из отношений. Но я предлагаю свести вложенные данные к минимуму, поскольку это повлияет на производительность