Проект инвентаризации. Как суммировать значения одноименных объектов в 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 имя, связанное с текущей группой, и установим текущее значение как сумму всех количеств всех кег в текущей группе.

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