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()))