Python | Сумма значений при повторении данных в другом списке

Итак, это что-то немного сумасшедшее, но я надеюсь, что это имеет решение. Я создаю веб-приложение для проверки продаж в издательстве. До сих пор у меня все было хорошо: я создал модель для продуктов (книг), для продаж... Все в порядке. Я использую charts.js для отображения данных. Вот код для представления:

def top_sales_view (request, *args, **kwargs):
    labels = [] #list for charts.js
    sold_copies = [] #list for charts.js
    billed = [] #list for charts.js
    books_all = Product.objects.all() #get all data from books
    for book in books_all:
        book_data=Sale.objects.filter(book = book.id ) #get all sales per book
        quantity_list = [] #set list of each quantity per sale
        income_list=[] #set list of each income per sale
        for data in book_data:
            quantity = data.quantity
            income = float(data.final_price)
            quantity_list.append(quantity) #list all quantity sales per book
            copies=sum(quantity_list) #sum all quantity sales per book
            income_list.append(income) #list all income sales per book
            billing=sum(income_list) #sum all income sales per book
        book ={
            'id': book.id,
            'title':book.title,
            'cost_center': book.cost_center,
            'data' : {
                'copies': copies,
                'billing' : billing
            }
        }
#------------- PARA CHARTS.JS -------------
        if book['cost_center'] not in labels: #chech if cost_center is not on the list
            labels.append(book['cost_center']) #if it isn't, add it
        if book['cost_center'] in labels:
            sold_copies.append(book['data']['copies'])
            print (sold_copies)


    
    my_context = {
        'labels': labels,
        'copies': sold_copies,
        'billing': billed,
    }
    return render (request, "top-ventas.html", my_context)

Дело в том, что есть две отдельные книги, потому что одна является вторым изданием первой, поэтому они учитывают их как отдельные книги, но у них одинаковые значения центров затрат (так как все доходы идут на покрытие одного и того же "проекта", скажем так). Мой вопрос: есть ли эффективный способ получить book['data']['copies'] и book['data']['billing'], проверить, есть ли соответствующий центр затрат в списке labels, и добавить/просуммировать их так, чтобы, хотя это разные книги, они суммировались для диаграммы? Я не уверен, ясно ли я выражаюсь.

Чтобы ваш chart.js работал, я заметил, что вам нужно только:

labels = []  # cost_center list of the books that have been saled
sold_copies = []  # quantity of copies of those books
billing = []  # how much money did those books sell

Тогда вы можете использовать ORM Django для получения результатов более чистым и быстрым способом:

top_sales_qs = Product.objects.annotate(
    bill=Sum('sale__bill'), copies=Sum('sale__quantity')
).order_by('-bill').values_list('cost_center', 'copies', 'bill') 

Чтобы сгруппировать их по center_cost значению, вы можете сделать:

labels_dict = {}
for label, copies, bill in top_sales_qs:
    current_val = labels_dict.get(label)
    if current_val is None:
        current_val = [label, 0, 0]
    current_label, current_copies, current_bill = current_val
    new_copies = current_copies + copies
    new_bill = current_bill + bill
    labels_dict[label] = [label, new_copies, new_bill]

Затем получить списки для chart.js

labels, sold_copies, billing = list(zip(*labels_dict.values()))
Вернуться на верх