Django模板中for循环与with标签无法获取debitore数据问题
Django模板无法访问动态键值数据的问题解决
问题背景
在Django视图中构建了包含动态命名键(如debitore_0、debitore_1)的上下文数据,已通过终端确认Session中的数据存在,但模板中尝试访问这些数据时页面无内容显示。
视图代码
def end(request): numero_debitori = request.session['numero_debitori'] dati_totali = {'numero_debitori': numero_debitori} if request.session['tipo_creditore'] == 'PF': dati_totali['creditore'] = { 'tipo': 'Persona Fisica', 'dati': { 'nome': request.session[f'nome'], 'cognome': request.session[f'cognome'], 'luogo_di_nascita': request.session[f'luogo_di_nascita'], 'data_di_nascita': request.session[f'data_di_nascita'], 'comune_di_residenza': request.session[f'comune_di_residenza'], 'indirizzo_di_residenza': request.session[f'indirizzo_di_residenza'], 'email': request.session[f'email'], 'pec': request.session[f'pec'], 'codice_fiscale': request.session[f'codice_fiscale'], 'partita_iva': request.session[f'partita_iva'], } } elif request.session['tipo_creditore'] == 'PJ': dati_totali[f'creditore'] = { 'tipo': 'Persona Giuridica', 'dati': { 'denominazione_sociale': request.session[f'denominazione_sociale'], 'comune_sede_principale': request.session[f'comune_sede_principale'], 'indirizzo_sede_principale': request.session[f'indirizzo_sede_principale'], 'email': request.session[f'email'], 'pec': request.session[f'pec'], 'codice_fiscale': request.session[f'codice_fiscale'], 'partita_iva': request.session[f'partita_iva'], } } for i in range(numero_debitori): if request.session[f'tipo_{i}'] == 'PF': dati_totali[f'debitore_{i}'] = { 'tipo': 'Persona Fisica', 'dati': { 'nome': request.session[f'nome_{i}'], 'cognome': request.session[f'cognome_{i}'], 'luogo_di_nascita': request.session[f'luogo_di_nascita_{i}'], 'data_di_nascita': request.session[f'data_di_nascita_{i}'], 'indirizzo_di_residenza': request.session[f'indirizzo_di_residenza_{i}'], 'codice_fiscale': request.session[f'codice_fiscale_{i}'], 'partita_iva': request.session[f'partita_iva_{i}'], } } elif request.session[f'tipo_{i}'] == 'PJ': dati_totali[f'debitore_{i}'] = { 'tipo': 'Persona Giuridica', 'dati': { 'denominazione_sociale': request.session[f'denominazione_sociale_{i}'], 'sede_principale': request.session[f'sede_principale_{i}'], 'codice_fiscale': request.session[f'codice_fiscale_{i}'], 'partita_iva': request.session[f'partita_iva_{i}'], } } context = {'dati_totali': dati_totali} return render(request, 'end.html', context)
原模板代码(无法正常工作)
{% for i in dati_totali %} {% with debitore_|add:i as debitore %} {{dati_totali.debitore.tipo}} {% endwith %} {% endfor %}
问题分析
- 遍历对象错误:直接遍历
dati_totali会遍历字典的所有键名(如numero_debitori、creditore),而不是预期的索引值i。 - 字符串拼接方式错误:
debitore_|add:i的写法不符合Django模板语法,无法正确拼接出debitore_0这类键名。 - 动态键访问方式错误:即使拼接出键名,
dati_totali.debitore是访问字典中名为debitore的固定键,而非变量debitore对应的动态键。
解决方案
方案一:修改视图结构(推荐)
将动态命名的debitore_{i}改为列表结构,模板遍历更简单清晰:
修改视图中dati_totali的初始化和循环逻辑:
def end(request): numero_debitori = request.session['numero_debitori'] # 新增debitori列表,用于存储所有债务人数据 dati_totali = {'numero_debitori': numero_debitori, 'debitori': []} # ... 原creditore处理代码保持不变 ... for i in range(numero_debitori): debitore_data = {} if request.session[f'tipo_{i}'] == 'PF': debitore_data = { 'tipo': 'Persona Fisica', 'dati': { 'nome': request.session[f'nome_{i}'], 'cognome': request.session[f'cognome_{i}'], 'luogo_di_nascita': request.session[f'luogo_di_nascita_{i}'], 'data_di_nascita': request.session[f'data_di_nascita_{i}'], 'indirizzo_di_residenza': request.session[f'indirizzo_di_residenza_{i}'], 'codice_fiscale': request.session[f'codice_fiscale_{i}'], 'partita_iva': request.session[f'partita_iva_{i}'], } } elif request.session[f'tipo_{i}'] == 'PJ': debitore_data = { 'tipo': 'Persona Giuridica', 'dati': { 'denominazione_sociale': request.session[f'denominazione_sociale_{i}'], 'sede_principale': request.session[f'sede_principale_{i}'], 'codice_fiscale': request.session[f'codice_fiscale_{i}'], 'partita_iva': request.session[f'partita_iva_{i}'], } } # 将债务人数据添加到列表中 dati_totali['debitori'].append(debitore_data) context = {'dati_totali': dati_totali} return render(request, 'end.html', context)
对应的模板代码:
{% for debitore in dati_totali.debitori %} <p>债务人类型:{{ debitore.tipo }}</p> <!-- 可继续访问债务人详细信息 --> {% if debitore.tipo == 'Persona Fisica' %} <p>姓名:{{ debitore.dati.nome }} {{ debitore.dati.cognome }}</p> {% else %} <p>企业名称:{{ debitore.dati.denominazione_sociale }}</p> {% endif %} {% endfor %}
方案二:不修改视图,通过模板过滤器访问动态键
如果无法修改视图,可自定义模板过滤器实现动态键访问:
- 在app目录下创建
templatetags/custom_filters.py文件:
from django import template register = template.Library() @register.filter def getitem(dictionary, key): return dictionary.get(key)
- 在模板中加载过滤器并使用:
{% load custom_filters %} {% for i in "x"|rjust:dati_totali.numero_debitori %} {% with debitore_key="debitore_"|add:forloop.counter0|stringformat:"s" %} <p>债务人类型:{{ dati_totali|getitem:debitore_key|getitem:"tipo" }}</p> {% endwith %} {% endfor %}
总结
方案一通过优化数据结构,让模板逻辑更直观,是更推荐的解决方案;方案二适合无法修改视图的场景,但需要额外维护模板过滤器。
内容的提问来源于stack exchange,提问作者Andrea
相关产品推荐
相关产品推荐

