Django中如何动态拼接变量名并调用对应模板变量
对应技术术语
你这个场景的通用技术术语是动态变量名访问,在你使用的Django框架场景下,也叫动态上下文键值调用,核心逻辑是把字符串拼接结果作为变量名/字典键,读取对应存储的数据。
具体实现方案
你当前的手写context冗余度极高,完全可以通过逻辑批量生成,同时模板端也可以通过自定义功能实现动态变量读取:
1. 后端context批量生成优化
不需要手动逐个写数百行赋值语句,用循环拼接key即可:
# 预定义所有需要处理的标的前缀 prefix_list = ['ESH4', 'ESH1', 'BTCH4', 'BTCH1', 'GBPH1', 'MESH1'] # 定义需要覆盖的数字范围,按你实际业务调整 num_range = list(range(0, 24)) + list(range(1,7)) context = {} for prefix in prefix_list: for num in num_range: # 统一格式化key,数字不足两位补前导0 var_key = f"{prefix}_{num:02d}" try: context[var_key] = PeriodProperties.objects.get(PK=var_key) except PeriodProperties.DoesNotExist: # 不存在的key默认设为空,避免模板报错 context[var_key] = None
2. 模板端动态读取变量
Django原生模板语法不支持直接用拼接字符串作为变量名,推荐两种实现方案:
方案A:自定义模板过滤器(最灵活)
首先在你的应用templatetags目录下新建自定义过滤器文件:
# custom_filters.py from django import template register = template.Library() @register.filter def get_by_key(dict_obj, key): return dict_obj.get(key, None)
模板中使用时先加载过滤器,拼接key后调用即可,比如你要读取{x}H1_{y}对应的变量:
{% load custom_filters %} <!-- 假设x是标的前缀变量,y是末尾数字变量 --> {% with target_key=x|add:"H1_"|add:y|stringformat:"02d" %} {% with target_var=target_key|get_by_key:context %} {% if target_var.isBreak == '!' %}!{% endif %} {% if target_var.isPUpFractal == 'pUP' %}pUP{% endif %} {% if target_var.isPDnFractal == 'pDN' %}pDN{% endif %} <br> {{target_var.maxRetracement|default_if_none:""}}|{{target_var.Current_RP|default_if_none:""}}|{{target_var.maxProjection|default_if_none:""}} {% endwith %} {% endwith %}
方案B:后端整理为嵌套字典(访问更简便)
如果你的变量规则固定,可以提前在后端把数据整理为两层嵌套结构,不需要在模板拼接key:
# 后端生成嵌套结构 context = {} period_data = {} # 第一层key为标的前缀 prefix_list = ['BTC', 'ES', 'MES', 'GBP'] for prefix in prefix_list: period_data[prefix] = {} # 第二层key为末尾数字 for num in range(0,24): db_key = f"{prefix}H1_{num:02d}" period_data[prefix][num] = PeriodProperties.objects.get(PK=db_key) context['period_data'] = period_data
模板中可以直接用两层变量读取对应值,不需要拼接:
<!-- 读取BTC标的、数字13对应的数据 --> {% if period_data.BTC.13.isBreak == '!' %}!{% endif %} {{ period_data.BTC.13.maxRetracement|default_if_none:"" }} <!-- 读取MES标的、数字18对应的数据 --> {% if period_data.MES.18.isUpFractal == 'UP' %}UP{% endif %}
内容的提问来源于stack exchange,提问作者kashix9
相关产品推荐
相关产品推荐

