简体   繁体   English

在 Django 模板中过滤反向查找

[英]Filtering a reverse lookup in Django template

I have a model that looks like this我有一个看起来像这样的模型

class Invoice(models.Model):
    inv_number = models.CharField(max_length=10, primary_key=True)
    customer = models.ForeignKey(Customer, on_delete=models.PROTECT)
    inv_date = models.DateField()

class Txn(models.Model): 
    invoice = models.ForeignKey(Invoice, on_delete=models.PROTECT)
    transaction_date = models.DateField()
    reference = models.CharField(max_length=12)
    amt = models.IntegerField()

I would like to display a report in my template that lists filtered invoices each with a sub-list of filtered transactions.我想在我的模板中显示一个报告,其中列出了过滤的发票,每个发票都有一个过滤交易的子列表。

In my view I have done the following:在我看来,我做了以下工作:

invoice_list = Invoice.objects.filter(customer=customer)

Which I pass into my template.我传递到我的模板中。 In the template, I do something like the following:在模板中,我执行以下操作:

{% for invoice in invoice_list %}
   {{ invoice.inv_number }}, {{ invoice.customer}}, {{ invoice.inv_date }}
   {% for txn in invoice.txn_set.all %}
      {{ txn.transaction_date }}, {{ txn.reference }}, {{ txn.amt }}
   {% endfor %}
{% endfor %}

This works great to show the entire transaction list per filtered invoice.这非常适合显示每个过滤发票的整个交易列表。 The question is, how does one also filter the list of transactions per invoice in the template - what if I wanted just the transactions within a certain date range or that match a specific reference?问题是,如何过滤模板中每张发票的交易列表 - 如果我只想要特定日期范围内的交易或匹配特定参考的交易怎么办? Is there maybe a way to pass a filter to the txn_set queryset per invoice in the view before putting the main queryset in the context and without converting them to lists?在将主查询集放入上下文之前,是否有可能将过滤器传递给视图中每个发票的 txn_set 查询集,而不将它们转换为列表?

Thank you for any response!感谢您的任何回应!

Suggestion: collect the invoices and transactions in the view, not in the template.建议:在视图中收集发票和交易,而不是在模板中。

With this view code you can reduce the amount of queries to 1, so it is a lot more optimal than your code (with queries the Txn table for each invoice):使用此视图代码,您可以将查询数量减少到 1,因此它比您的代码优化得多(查询每个发票的Txn表):

# build basic query
qs = Txn.objects.select_related('invoice')\
    .filter(invoice__customer=customer)\
    .order_by('transaction_date')

# add filtering; here is an example, but it could be with date filter as well
reference = request.GET.get('reference', '')
if len(reference) > 0:
    qs = qs.filter(reference__icontains=reference)

invoice_dict = {}
for txn in qs:
    # add the Invoice if it does not exist yet
    if txn.invoice_id not in invoice_dict:
        invoice_dict[txn.invoice_id] = {
            'invoice': txn.invoice,
            'txn_list': [],
        }

    # add the Txn
    invoice_dict[txn.invoice_id]['txn_list'].append(txn)

# sort by Invoice date
invoice_data_list = sorted(
    invoice_dict.values(),
    key=lambda x: x['invoice'].inv_date)

Then in your template:然后在您的模板中:

{% for elem in invoice_data_list %}
    {{ elem.invoice.inv_number }}
    {{ elem.invoice.customer}}
    {{ elem.invoice.inv_date }}

    {% for txn in elem.txn_list %}
         {{ txn.transaction_date }}
         {{ txn.reference }}
         {{ txn.amt }}
    {% endfor %}
{% endfor %}

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

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