我有一组导入的银行帐户条目,按日期和序列号在每个日期内提供。
我正在使用django-tables2来显示数据,我在渲染视图之前添加了一个我计算的运行总计列。
为此,我尝试使用以下代码向查询集添加字段:
import django_tables2 as tables
from django_tables2 import RequestConfig
from .models import Bank, BankImportFile, ImportFileEntry
... other imports
class BankListingTable(tables.Table):
memo = tables.Column(verbose_name = 'Description')
total = tables.Column(verbose_name = 'Running Total')
class Meta:
model = ImportFileEntry
attrs = {'class': 'paleblue'}
def bank_listing(request, bankname):
bank = get_object_or_404(Bank, pk=bankname)
qs = ImportFileEntry.objects.filter(account=Bank(bank)).order_by('date', 'seq')
total = 0
for row in qs:
total += row.amount
row.total = total
table = BankListingTable(qs)
RequestConfig(request).configure(table)
return render(request, 'banking/bank_transactions.html', {'table': table, 'bank': bank})
如果我在pdb
中逐步执行此代码,我可以同时检查row.total
和qs[<row number>].total
,并且它们似乎有正确的数据。
然而,在渲染表中,我在总列中得到的是--
如果我将queryset
转换为列表并将其他所有内容保持不变,则可以正常运行:
def bank_listing(request, bankname):
bank = get_object_or_404(Bank, pk=bankname)
qs = ImportFileEntry.objects.filter(account=Bank(bank)).order_by('date', 'seq')
qs = list(qs) # ADDED THIS LINE AND IT WORKS
total = 0
for row in qs:
total += row.amount
row.total = total
table = BankListingTable(qs)
RequestConfig(request).configure(table)
return render(request, 'banking/bank_transactions.html', {'table': table, 'bank': bank})
我的queryset
很大,因为它是商业银行帐户的9年历史记录,因此将其复制到list
似乎非常低效。
我在StackOverflow
上看到过其他一些似乎暗示我的原始代码应该有用的例子,pdb测试意味着应该这样做。这是django-tables2
吗?
答案 0 :(得分:1)
正如我在评论中所说,你所做的就是我的工作。但是,我不建议使用for
循环评估查询,因为这会将您的查询集加载到内存中(它实际上与使用list
具有相同的效果)。相反,我建议在查询中添加一个包含运行总和的额外行。
要做到这一点,您应该使用extra
queryset method将额外字段添加到您的查询集。要了解如何使用SQL获取运行总计,您可以检查此问题的答案:How to get running sum of a column in sql server
另外,既然你提到你的查询集很大,你应该为你的表添加分页 - 如果你用你的查询集评估你的查询集,你将不从分页中受益for-loop
。如果您在实施extra()
方法时遇到问题,请随时再次询问。
更新:回答OP的评论(我不确定您的表格和字段的名称,但我会猜测:
SELECT amount, (
select sum(amount) FROM ImportFileEntry ife1 where ife1.date < ife.date
) + (
select sum(amount) FROM ImportFileEntry ife2 where ife2.date = ife.date and ife2.seq < ife.seq
) as running_total FROM ImportFileEntry ife order by ife.date, ife.seq
一个(复杂)查询 - as running_total
将是extra()
queryset方法将创建的内容:)