Django 注释总和

Bil*_*ong 6 python django python-3.x

我正在尝试对查询集中包含多行的列进行简单求和。我的直接问题是(a)如何设置get_queryset()以包含列的总和以及(b)如何访问模板中的该元素?继这个问题之后:

#models.py
class ItemPrice( models.Model ):
    price = models.DecimalField ( max_digits = 8, decimal_places=2 )
    ....
Run Code Online (Sandbox Code Playgroud)

提供了两个答案 - 一个使用.aggregate()我不相信会返回查询集的方法,并且.annotate()使用我相信将一个项目附加到查询集的方法。

因此,我预计以下内容会在此视图中的对象列表中添加另一个项目:

#views.py
def get_queryset(self):
    # generate table and filter down to a subquery.
    queryset = ItemPrice.objects.filter(<some_filter>)
    # sum the price for each row in the subquery.
    queryset = queryset.annotate(totals=Sum('price'))
    return queryset
Run Code Online (Sandbox Code Playgroud)

然后在模板中,我将能够像这样迭代对象列表:

#template.html
{% for item in object_list %}
    {{ item }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

期望其中一项(最后一项?)是price_sum并且余额可以作为price_sum.price

但是,当我将以下内容添加到模板中时,我得到每个订单项的价格 - 没有求和。

{% for item in object_list %}
    {{ item.totals }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

但是,我无法访问该项目。不知道是视图修改的问题get_queryset()还是模板的问题?

And*_*nda 6

如果你想使用:

ItemPrice.objects.filter(<some_filter>).annotate(totals=Sum('price'))
Run Code Online (Sandbox Code Playgroud)

总计始终与“价格”相同

注释(关于 Sum)使用如下:

如果您有这些型号:

class ItemPrice( models.Model ):
    price = models.DecimalField ( max_digits = 8, decimal_places=2 )
    other_model = models.ForeignKey(
          to=OtherModel, 
          related_name="item_prices", 
          on_delete=models.SET_NULL
    )

# related_name - if I set related_name I can use like this
# other_model_object.item_prices.all() - this code return all 
# ItemPrices with other_model_id=other_model_object.id

class OtherModel(models.Model):
    some_field = models.CharField(max_lenght=256)
Run Code Online (Sandbox Code Playgroud)

并且您想要具有一个 OtherModel 外键的所有 ItemPrices 的所有价格,您应该使用以下代码:

queryset = OtherModel.objects.annotate(
       total_prices=Sum('item_prices__price')
).filter(<your_filters>)
Run Code Online (Sandbox Code Playgroud)

之后你可以使用:

for obj in queryset:
    print(obj.total_prices)
Run Code Online (Sandbox Code Playgroud)

或者,如果您需要所有价格的总和,您应该使用总计

ItemPrices.objects.aggregate(all_sum=Sum('price'))
Run Code Online (Sandbox Code Playgroud)

这段代码返回 dict(或类似的东西,我不记得确切了)像这样

{'all_sum': 1250}
Run Code Online (Sandbox Code Playgroud)

all_sum - 数据库表中所有对象的总和

  • 你不能组合它,因为查询集返回相同的对象,但你需要返回许多相似的对象(结构)和一个只有一个字段(总计)的对象 (2认同)

And*_*nda 5

如果您想向模板添加数据

queryset = ItemPrice.objects.filter(<your_filter>)
totals = queryset.aggregate(sum=Sum('price').get('sum')

context  = {
    'object_list': queryset,
    'totals': totals,
}
render(request, '<name_of_your_template>.html', context)
Run Code Online (Sandbox Code Playgroud)

并在你的模板中

{% for item in object_list %}
    # price of item
    {{ item.price }}
{% endfor %}
# total price
{{ totals }}
Run Code Online (Sandbox Code Playgroud)