Как сгруппировать все связанные данные и вернуть их как значения в django? - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть 3 модели:

class City(models.Model):
    name = models.CharField(max_length=150)

class Person(models.Model):
    name = models.CharField(max_length=150)
    city = models.ForeignKey(
        City, related_name="persons", on_delete=models.PROTECT)

class Fruit(models.Model):
    quantity = models.IntegerField()
    price = models.IntegerField()
    person = models.ForeignKey(Person, related_name="fruits")
    city = models.ForeignKey(City, related_name="fruits")

Я хочу сгруппировать все данные по городам и получить общую стоимость фруктов по городам и общее количество по городам, а также по людям.

Я хочу, чтобы мой результат был примерно таким:

{'city': 'XYZ', 'total_fruits': 20, 'total_price': 123, 'persons': [{'name': 'foo', 'total_fruits': 5}, {'name': 'bar', 'total_fruits': 6}]}

Я пробовал что-то вроде:

queryset = City.objects.annotate(total_price = Sum('persons__fruits__price'), total_fruits= Count('persons__fruits'))

city_list = []
for city in queryset:
   abc = {'name': city.name, 'total_fruits':company.total_fruits, 
          'total_price':company.total_price}
   persons = city.persons.annotate(total_fruits= Count('fruits')).values('name','total_fruits')
   abc.update({'persons':persons })
   city_list.append(abc)

Что не очень эффективно. Я хочу удалить это l oop и минимизировать запросы. Заранее спасибо. Дайте мне знать, где я не прав.

1 Ответ

0 голосов
/ 19 февраля 2020

Вы можете сократить его до двух запросов:

city_qs = City.objects.annotate(total_price = Sum('persons__fruits__price'), total_fruits=Count('persons__fruits')).prefetch_related('persons')

person_qs = Person.objects.annotate(total_fruits=Count('fruits')).values('name','total_fruits')

city_list = []
for city in city_qs:
    for person_id in city.persons:
         person_data = person_qs[person_id]
    ...
    city_list.append(abc)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...