Django: Tính Tổng giá trị cột thông qua truy vấn


92

Tôi có một người mẫu

class ItemPrice( models.Model ):
     price = models.DecimalField ( max_digits = 8, decimal_places=2 )
     ....

Tôi đã thử điều này để tính tổng pricetrong bộ truy vấn này:

items = ItemPrice.objects.all().annotate(Sum('price'))

có gì sai trong truy vấn này? hoặc có cách nào khác để tính Tổng của pricecột?

Tôi biết điều này có thể được thực hiện bằng cách sử dụng vòng lặp for trên bộ truy vấn nhưng tôi cần một giải pháp thanh lịch.

Cảm ơn!


Điều này có trả lời câu hỏi của bạn không? Truy vấn Django SUM?
Flimm

Câu trả lời:


196

Có thể bạn đang tìm kiếm aggregate

from django.db.models import Sum

ItemPrice.objects.aggregate(Sum('price'))
# returns {'price__sum': 1000} for example

1
Làm cách nào tôi có thể nhận được tổng số có giá = 5000?
Anuj Sharma

6
Hãy nhớ trả về từ điển không phải float / integer, ví dụ {'price__sum':1000}. Có thể nhận float / integer vớiyourdict['price__sum']
Josh

35

Annotate thêm một trường vào kết quả:

>> Order.objects.annotate(total_price=Sum('price'))
<QuerySet [<Order: L-555>, <Order: L-222>]>

>> orders.first().total_price
Decimal('340.00')

Aggregate trả về một dict với kết quả được hỏi:

>> Order.objects.aggregate(total_price=Sum('price'))
{'total_price': Decimal('1260.00')}

Tôi đánh giá cao việc bạn chỉ ra cách chỉ định keyđể lưu trữ tổng valuevào.
MikeyE

32

Sử dụng tham khảo .aggregate(Sum('column'))['column__sum']ví dụ của tôi bên dưới

sum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']

5

Sử dụng trình biên dịch cProfile , tôi thấy rằng trong môi trường phát triển của mình, việc tổng hợp các giá trị của một danh sách sẽ hiệu quả hơn (nhanh hơn) so với việc sử dụng tổng hợp Sum(). ví dụ:

sum_a = sum([item.column for item in queryset]) # Definitely takes more memory.
sum_b = queryset.aggregate(Sum('column')).get('column__sum') # Takes about 20% more time.

Tôi đã thử nghiệm điều này trong các bối cảnh khác nhau và có vẻ như việc sử dụng aggregateluôn mất nhiều thời gian hơn để tạo ra cùng một kết quả. Mặc dù tôi nghi ngờ có thể có lợi ích về trí nhớ khi sử dụng nó thay vì tổng hợp một danh sách.


1
Ngoài ra, sử dụng một biểu thức máy phát điện thay vì một danh sách: sum_a = sum(item.column for item in queryset). Sự khác biệt duy nhất là []s bị loại bỏ . Điều này tiết kiệm không gian bộ nhớ để tính toán toàn bộ danh sách trước khi sum()lặp lại nó.
Code-Apprentice
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.