Представление Django для объединения данных родительской и дочерней таблиц

У меня есть две модели Django с отношением по внешнему ключу:

class Parent(models.Model):
   id = models.IntegerField()
   parent_name = models.CharField()


class Child(models.Model)
   id = models.IntegerField()
   child_name = models.CharField()
   parent = models.ForeignKey(Parent, related_name='parent', on_delete=models.CASCADE)

Обе таблицы имеют большой объем, поэтому нужно что-то очень эффективное. Какой лучший способ написать эффективное представление на django, чтобы вернуть json в виде:

Ожидаемый JSON:

[
    {
        "id": 1,
        "parent_name": "Elon",
        "childs":
        [
           {
              "id": 101,
              "child_name": "Elon son"
          },

          {
              "id": 101,
              "child_name": "Elon daughter"
          }        
       ]
    },
  {
        "id": 2,
        "parent_name": "Jeff",
        "childs":
        [
           {
              "id": 101,
              "child_name": "Jeff son"
          },

          {
              "id": 101,
              "child_name": "Jeff daughter"
          }        
       ]
    }
]

Следующее представление вернет данные JSON, сгенерировав всего два запроса к базе данных, используя prefetch_related() (использование children в качестве related_name для Child.parent имеет больше смысла, поскольку Parent.children будет RelatedManager для доступа к дочерним элементам родителя - поэтому я использовал его в этом примере).

from django.http import JsonResponse

def my_view(request):
    queryset = Parent.objects.all().prefetch_related("children")
    data = []
    for p in queryset:
        parent_data = {"id": p.pk, "parent_name": p.parent_name}
        parent_data["childs"] = [{"id": c.pk, "child_name": c.child_name} 
                                  for c in p.children.all()]
        data.append(parent_data)
    return JsonResponse(data)

Вы также можете рассмотреть возможность использования QuerySet.values(), если вы хотите, чтобы queryset немедленно возвращал список словарей, но если вам нужны вложенные объекты/словари, итерация по queryset и построение списка, как в примере выше, вероятно, будет проще.

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