简体   繁体   English

添加到Django查询集的字段在django-tables2中不起作用

[英]Field added to django querysets not working in django-tables2

I have a set of imported bank account entries that are oredered by date and sequence number within each date. 我有一组导入的银行帐户条目,这些条目按日期和每个日期内的序列号排序。

I'm using django-tables2 to display the data, to which I'm adding a running total column that I calculate before rendering the view. 我正在使用django-tables2来显示数据,并在其中添加了在渲染视图之前计算的运行总计列。

To do this I'm trying to add a field to the query set with the following code: 为此,我尝试使用以下代码向查询集中添加一个字段:

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}) 

If I step through this code in pdb I can examine both row.total and qs[<row number>].total and they appear to have the correct data. 如果我在pdb逐步执行此代码,则可以同时检查row.totalqs[<row number>].total ,它们似乎具有正确的数据。

Yet in the rendered table all I get in the total column is -- 但是在呈现的表中,我在total列中得到的全部是--

If I convert my queryset to a list and leave everything else unchanged it works: 如果我将转换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}) 

My queryset is large as it is a 9-year history of a business bank account so it seems very inefficient to copy it to a list . 我的查询集很大,因为它是一家商业银行帐户queryset 9年的历史,因此将其复制到list似乎效率很低。

I've seen other examples on StackOverflow that seem to imply my original code should work and pdb testing implies it should. 我在StackOverflow上看到了其他示例,这些示例似乎暗示我的原始代码应该工作,而pdb测试暗示它应该可以工作。 Is this something in django-tables2 ? django-tables2有这个东西吗?

As I said in my comment, what you did is working in my case. 正如我在评论中说的那样,您的工作在我的情况下是有效的。 However, I wouldn't recommend evaluating the query with the for loop since this will load your queryset to memory (it actually has the same effect as using list ). 但是,我不建议使用for循环来评估查询,因为这会将查询集加载到内存中(实际上与使用list具有相同的效果)。 Instead, I'd recommend adding an extra row to your query that would contain the running sum. 相反,我建议向您的查询添加额外的一行,其中应包含正在运行的总和。

To do do that you should use the extra queryset method to add the extra field to your queryset. 要做到做到这一点,你应该使用extra查询集方法的额外字段添加到您的查询集。 To find out how to get the running total with SQL you can check the answer to this question: How to get running sum of a column in sql server 若要了解如何使用SQL获取运行总计,可以检查以下问题的答案: 如何获取sql server中列的运行总计。

Also, since you mention that your queryset is large you should add pagination to your table -- and you will not benefit from pagination if you evaluate your queryset with the for-loop . 此外,由于你提到你的查询集大,你应该添加分页您的表-如果您评估与您的查询集,你将不会从分页受益for-loop Feel free to ask again if you have trouble implementing the extra() method. 再次询问您是否在实现extra()方法时遇到问题。

Update : To answer OP's comment (I am not sure about the names of your tables & fields but I'll make a guess: 更新 :要回答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

One (complex) query -- the as running_total would be what the extra() queryset method would create :) 一个(复杂)查询as running_total将是extra() queryset方法将创建的内容:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM