问题
I have the following Django (2.1) model:
class Sales(models.Model):
product_name = models.ForeignKey(Product)
category = models.ForeignKey(Category)
sales= models.DecimalField(max_digits=25)
I would like to receive the sum of all sales for each different product_name
instance that is the same.
For example, I have the following sales by product_name
:
- DVDs = 6.00
- DVDs = 6.00
- Books = 14.00
- Books = 6.00
- Magazines = 4.00
- Magazines = 4.00
I can use Sales.objects.aggregate(sales=Sum('sales'))
to get the total aggregate of all sales instances combined but how can I get the aggregate for product_name
separately; i.e. Books ($20.00), DVDs ($12.00), Magazines ($8.00)?
回答1:
We can use .annotate
for this in combination with .values
:
Sales.objects.values(
'product_name'
).annotate(
total_sales=Sum('sales')
).order_by('product_name')
Note that product_name
is a ForeignKey
, so we will get the id of the Product
object, like:
<QuerySet [
{'product_name': 1, 'total_sales': 12.00 },
{'product_name': 2, 'total_sales': 20.00 },
{'product_name': 3, 'total_sales': 8.00 } ]>
Therefore I think you are probably more interested in querying with the Product
object instead, something like:
Product,objects.values(
'name'
).annotate(
total_sales=Sum('sales__sales')
).order_by('name')
Which then produces:
<QuerySet [
{'name': 'Books', 'total_sales': 20.00 },
{'name': 'DVDs', 'total_sales': 12.00 },
{'name': 'Magazines', 'total_sales': 8.00 } ]>
These are thus QuerySet
s that contain dictionaries: each dictionary has two keys: 'name'
and total_sales'
, and we can thus iterate over the dictionaries and process the key-value pairs.
We used total_sales
since my experience is that naming the aggregate the same as another field typically results in some problems. First of all, it is not really clear that this is different from the sales
field. Furthermore in some versions of Django this could result in invalid queries.
Note: since a
ForeignKey
refers to an object of the related model. I advise to renameproduct_name
to justproduct
.
来源:https://stackoverflow.com/questions/52339136/django-query-to-aggregate-the-sum-for-matching-instances-in-the-same-field