【问题标题】:Field added to django querysets not working in django-tables2添加到 django 查询集中的字段在 django-tables2 中不起作用
【发布时间】:2014-01-31 16:27:24
【问题描述】:

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

我正在使用 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 里的东西吗?

【问题讨论】:

  • 您好!我尝试做你所做的(没有转换为list),它工作正常。可能你错过了什么......

标签: python django django-queryset django-tables2


【解决方案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() 查询集方法将创建的内容:)

【讨论】:

  • 我在示例中看不到解决方案。似乎在查询中的每条记录上都有一个运行总计,我需要运行一个子查询来计算 UP TO and include this record> 这将是对 n 条记录的 n 次查询。我的UP TO 也很重要,因为我的排序顺序是日期然后是seq。我正在使用 pgSQL。感谢您的回复以及您可以提供的任何进一步建议
  • 是的,这将是对 n 行的 n 次查询(实际上它将是 一个 复杂查询)。但是,如果您按照我的建议使用分页,即使您的数据库中有数百万行,您也会有一个包含 25 行的页面。另一方面,如果您使用 for 循环或列表评估查询集,则需要将所有内容都记在内存中。
  • 你能给我一个提示或链接,以 one complex query 的形式添加字段 running_total = amount 所有记录的总和(日期
猜你喜欢
  • 1970-01-01
  • 2018-03-10
  • 2018-05-25
  • 1970-01-01
  • 2016-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多