问题描述
可能的重复:
Django 模板不能循环 defaultdict
我想知道为什么我的 defaultdict(list)
在我的 views.py 中测试时会显示,但是当我去显示模板上的数据时,我什么也没得到,甚至没有错误.
I am wondering why my defaultdict(list)
will show when I test it in my views.py but when I go to show the data on my template, I get nothing, not even an error.
有什么建议吗?
这是我的 views.py - confirm_list 是我的 defaultdict(list)
Here is my views.py - confirm_list is my defaultdict(list)
def confirmations_report(request, *args, **kwargs):
from investments.models import Investment, InvestmentManager
from reports.forms import ConfirmationsForm
from collections import defaultdict
import ho.pisa as pisa
import cStringIO as StringIO
import os.path
confirm_list = defaultdict(list)
context = {}
if request.POST:
form = ConfirmationsForm(request.POST)
if form.is_valid():
start_date = form.cleaned_data['start_date']
end_date = form.cleaned_data['end_date']
investments = Investment.objects.all().filter(contract_no = "",maturity_date__range=(start_date, end_date)).order_by('financial_institution')
for i in investments:
confirm_list[i.financial_institution.pk].append({
'fi':i.financial_institution,
'fi_address1': i.financial_institution.address1,
'fi_address2': i.financial_institution.address2,
'fi_city': i.financial_institution.city,
'fi_prov': i.financial_institution.state_prov,
'fi_country': i.financial_institution.country,
'fi_postal': i.financial_institution.postal,
'primary_owner': i.plan.get_primary_owner().member,
'sin': i.plan.get_primary_owner().member.client.sin,
'type': i.product.code,
'purchase_amount': i.amount,
'purchase_date': i.start_date,
})
context['investments'] = investments
context['confirmlist'] = confirm_list
for key, value in confirm_list.items():
print key, value
context['inv'] = investments
if request.POST.has_key('print_report_submit'):
context['show_report'] = True
context['mb_logo'] = os.path.join(os.path.dirname(__file__), "../../../media/images/mb_logo.jpg")
html = render_to_string('reports/admin/confirm_report_print.html', RequestContext(request,context))
result = StringIO.StringIO()
pdf = pisa.pisaDocument(StringIO.StringIO(html.encode("ISO-8859-1")), result)
response = HttpResponse(result.getvalue(), mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=unreceived-confirmations.pdf'
return response
else:
form = ConfirmationsForm()
context['form'] = form
return render_to_response('reports/admin/confirm_report.html', RequestContext(request, context))
但是当我这样做时:
for key, value in confirm_list.items():
print key, value
在我的模板上像这样:
{% extends 'reports/admin/base.html' %}
{% load humanize %}
{% block report_html %}
<h3>Unreceived Confirmations Report</h3>
<form method="post" action="">
<table>
<tr>
<td>
<strong> {{ form.start_date.label }}</strong> {{ form.start_date }}
<strong>{{ form.end_date.label }}</strong> {{ form.end_date }}
</td>
</tr>
</table>
<input type="submit" value="View Report">
<input type="submit" name="print_report_submit" value="Print Report"/>
</form>
{% for key, value in confirmlist.items %}
{{ key }} - {{ value }}
{% endfor %}
{% endblock %}
我一无所获.
这是我在 views.py 中测试时得到的输出示例
Here is a sample of the output I get when testing in the views.py
33 [{'fi_address1': u'Scotiabank FAS', 'fi_country': u'Canada', 'fi_address2': u'20 Queen Street West, Suite 2600', 'fi_city': u'TORONTO', 'fi': <FinancialInstitution: NATIONAL TRUST>, 'fi_prov': u'Ontario', 'fi_postal': u'### ###', 'purchase_amount': Decimal('30000.00'), 'purchase_date': datetime.date(2011, 6, 27), 'type': u'GIC', 'sin': u'###/###/###', 'primary_owner': <Member: #, #>}]
推荐答案
这是因为 Django 模板语言的处理方式 变量查找.当您尝试遍历字典项时,
This happens because of the way the Django template language does variable lookups. When you try to loop through the dictionaries items,
{% for key, value in confirmlist.items %}
Django 首先对 confirmlist['items']
进行字典查找.由于这是一个 defaultdict
,因此返回一个空列表.
Django first does a dictionary lookup for confirmlist['items']
. As this is a defaultdict
, an empty list is returned.
这是一个残酷的陷阱,我也被刺痛了!
It's a cruel gotcha, that I've been stung by as well!
要解决此问题,请将 defaultdict 转换为字典,然后再将其添加到模板上下文中.
To work around this problem, convert your defaultdict into a dictionary before adding it to the template context.
context['confirmlist'] = dict(confirm_list)
或者,正如 sebastien trottier 在他的对类似问题的回答中所解释的那样,设置在添加到模板上下文之前将 default_factory
改为 None
.
Or, as explained by sebastien trottier in his his answer to a similar question, set default_factory
to None
before adding to the template context.
confirm_list.default_factory = None
context['confirmlist'] = confirm_list
这篇关于我的 defaultdict(list) 不会出现在模板上,但在我看来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!