字段添加到django查询集不能在django-tables2中工作

时间:2014-01-31 16:27:25

标签: python django django-queryset django-tables2

我有一组导入的银行帐户条目,按日期和序列号在每个日期内提供。

我正在使用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.totalqs[<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吗?

1 个答案:

答案 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方法将创建的内容:)