Django模板中如何通过动态变量名遍历对应上下文数据?
Django模板中通过动态变量名遍历上下文数据的解决方案
问题原因
你之前的写法无效,是因为object.name|add:"_header"只是拼接出了字符串(比如"test1_header"),但Django模板不会自动把这个字符串解析为上下文变量名,而是把字符串本身当作遍历对象——遍历字符串的每个字符自然不会有你要的结果。
解决方案
方法1:在视图中直接给模型实例附加数据(推荐)
修改ListView的get_context_data方法,把每个对象对应的header和body数据直接绑定到模型实例上,模板里直接调用即可:
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) # 先把所有t_name对应的header/body数据整理成字典 data_map = {} # 替换成你实际获取t_name、db_oper、db_header的逻辑 for t_name in [obj.name for obj in context['object_list']]: db_oper = ... # 你的test1_header对应的数据获取逻辑 db_header = ... # 你的test1_body对应的数据获取逻辑 data_map[t_name] = { 'header': db_oper, 'body': db_header } # 给每个object实例附加对应的header和body数据 for obj in context['object_list']: obj.header_data = data_map.get(obj.name, {}).get('header', []) obj.body_data = data_map.get(obj.name, {}).get('body', []) return context
模板中直接遍历实例属性:
{% for object in object_list %} <!-- 遍历header数据 --> {% for item in object.header_data %} <!-- 处理你的逻辑 --> {% endfor %} <!-- 遍历body数据 --> {% for item in object.body_data %} <!-- 处理你的逻辑 --> {% endfor %} {% endfor %}
方法2:自定义模板标签获取上下文变量
如果不想修改视图逻辑,可以自定义一个能从上下文里通过变量名取值的模板标签:
- 在你的app下创建
templatetags/custom_tags.py文件(如果没有templatetags目录,先创建并添加__init__.py):
from django import template register = template.Library() @register.simple_tag(takes_context=True) def get_context_var(context, var_name): # 从上下文获取指定名称的变量,默认返回空列表 return context.get(var_name, [])
- 模板中加载并使用这个标签:
{% load custom_tags %} {% for object in object_list %} <!-- 获取header数据 --> {% get_context_var object.name|add:"_header" as header_data %} {% for item in header_data %} <!-- 处理逻辑 --> {% endfor %} <!-- 获取body数据 --> {% get_context_var object.name|add:"_body" as body_data %} {% for item in body_data %} <!-- 处理逻辑 --> {% endfor %} {% endfor %}
方法3:将数据打包为字典传入上下文
把所有header/body数据整理成一个嵌套字典传入上下文,模板中通过对象名称直接索引:
视图中修改get_context_data:
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) data_groups = {} # 替换成你的数据获取逻辑 for t_name in [obj.name for obj in context['object_list']]: data_groups[t_name] = { 'header': ..., # 对应t_name_header的数据 'body': ... # 对应t_name_body的数据 } context['data_groups'] = data_groups return context
模板中使用:
{% for object in object_list %} {% with group=data_groups|get:object.name %} {% for item in group.header %} <!-- 处理header逻辑 --> {% endfor %} {% for item in group.body %} <!-- 处理body逻辑 --> {% endfor %} {% endwith %} {% endfor %}
注:这里需要一个
get过滤器来安全索引字典,你可以自定义一个简单的get过滤器:@register.filter def get(dictionary, key): return dictionary.get(key, {})
总结
优先推荐方法1,它让视图逻辑更清晰,模板代码更简洁,也避免了模板中复杂的变量解析操作。
内容的提问来源于stack exchange,提问作者jaszewski
相关产品推荐
相关产品推荐

