Проект инвентаризации. Как суммировать значения одноименных объектов в queryset в Django
У меня несколько пивоварен с несколькими сортами пива. Некоторые из них одинаковые. Мне нужно предоставить компании детализированный итог. Этот код выполняет итерацию по набору запросов, находит дублирующиеся названия, суммирует количество и затем добавляет его в словарь. Если дубликатов нет, он сразу попадает в словарь. Я новичок в Python и Django, поэтому код элементарный и неуклюжий. Пожалуйста, посоветуйте мне более элегантные и лаконичные методы решения этой проблемы. Спасибо!
def index_inventory(request):
keg_totals = {}
keg_data = Kegs.objects.all()
counter = 0
for keg in keg_data:
counter2 = counter + 1
while counter2 <= (len(keg_data)) -1:
if (keg_data[counter].beer) == (keg_data[counter2].beer):
(keg_data[counter2].quantity) =(keg_data[counter2].quantity)+
(keg_data[counter].quantity)
counter2 += 1
else:
keg_totals[keg.beer] = keg.quantity
counter2 += 1
counter += 1
context = {
'keg_totals' : keg_totals,
}
return render(request, 'inventory/index_inventory.html', context)
<QuerySet [<Kegs: 33rd State 7.75 -5>, <Kegs: 33rd State 7.75 -10>, <Kegs: Fresh Harvest 15 -35>, <Kegs: Fresh Harvest 15 -30>, <Kegs: Hammerhead 15 -25>, <Kegs: Hammerhead 15 -15>, <Kegs: Hammerhead 15 -40>, <Kegs: Purple Haze 15 -20>, <Kegs: Purple Haze 15 -25>, <Kegs: Purple Haze 7.75 -5>, <Kegs: Sunflower 15 -30>, <Kegs: Sunflower 15 -10>, <Kegs: Terminator Stout 15 -20>, <Kegs: Terminator Stout 5 -5>, <Kegs: xxx -0>]>
Название и размер бочонка с количеством.
Предположим, что у вас есть коллекция бочонков:
class Keg:
def __init__(self, beer, quantity):
self.beer = beer
self.quantity = quantity
kegs = [
Keg("Ale", 10),
Keg("Lager", 25),
Keg("Ale", 2),
Keg("Stout", 4),
Keg("Lager", 10)
]
Вы можете сделать:
from itertools import groupby
from operator import attrgetter
key = attrgetter("beer")
keg_totals = { beer: sum(keg.quantity for keg in group) for beer, group in groupby(sorted(kegs, key=key), key=key)}
print(keg_totals)
Выход:
{'Ale': 12, 'Lager': 35, 'Stout': 4}
Объяснение:
Сначала мы создаем отсортированную версию коллекции бочонков через sorted(kegs, key=attrgetter("beer"))
. Мы сортируем на основе key
, что в данном случае означает, что мы сортируем на основе лексикографического упорядочивания свойства beer
каждого бочонка (мы сортируем в алфавитном порядке на основе beer
имени):
[
Keg("Ale", 10),
Keg("Ale", 2),
Keg("Lager", 25),
Keg("Lager", 10),
Keg("Stout", 4)
]
Затем мы создаем список групп на основе бочонков в этой отсортированной коллекции, которые находятся рядом друг с другом и имеют одно и то же beer
название:
[
[ Keg("Ale", 10), Keg("Ale", 2)],
[ Keg("Lager", 25), Keg("Lager", 10)],
[ Keg("Stout", 4)]
]
В данном примере у нас есть три группы.
Затем, используя словарь-понятие, мы создаем словарь: Для каждой группы в нашем списке групп, установим текущий ключ как beer
имя, связанное с текущей группой, и установим текущее значение как сумму всех количеств всех кег в текущей группе.