Django模板使用'=='整数比较时渲染报错问题排查
Django模板整数比较报错问题解决
问题描述
在Django模板中使用==进行整数比较时触发TemplateSyntaxError,报错提示无法解析==1部分。
视图函数代码
def mailtemplate_GetSchema(request, id=None): if id == None: svars = [] this_var = {} this_var['s_id']=str(uuid4()) this_var['varname'] = f"varname_{this_var['s_id']}" this_var['varlabel'] = f"varlabel_{this_var['s_id']}" this_var['vartype'] = f"vartype_{this_var['s_id']}" this_var['varformat'] = f"varformat_{this_var['_sid']}" this_var['varname_value'] = '' this_var['varlabel_value'] = '' this_var['vartype_value'] = 1 this_var['varformat_value'] = '' svars.append(this_var) return render(request, 'mailtemplate_all.html', {'svars': svars}) try : obj = MailTemplate.objects.get(pk=id) schema = obj.schema schema = json.loads(schema) # it's a list of dictionary vars = [] for s in schema: this_var = {} this_var['field_id']=str(uuid4()) this_var['varname'] = f"varname_{this_var['field_id']}" this_var['varlabel'] = f"varlabel_{this_var['field_id']}" this_var['vartype'] = f"vartype_{this_var['field_id']}" this_var['varformat'] = f"varformat_{this_var['field_id']}" this_var['varname_value'] = s.get('name','') this_var['varlabel_value'] = s.get('label','') this_var['vartype_value'] = s.get('type',1) this_var['varformat_value'] = s.get('format',None) if this_var['varformat_value'] == '': this_var['varformat_value']=False vars.append(this_var) print(f'VARS:{vars}') return render(request, 'mailtemplate_all.html', {'vars': vars}) except MailTemplate.DoesNotExist: return HttpResponseNotFound()
模板文件mailtemplate_all.html代码
{% for v in vars%} <div id={{ v.field_id }} class="divTableRow"> <div class="divTableCell"> <input type="text" name={{v.varname}} value={{ v.varname_value}} class="vTextField" maxlength="20" > </div> <div class="divTableCell"> <input type="text" name={{v.varlabel}} value={{ v.varlabel_value}} class="vTextField" maxlength="20" > </div> <div class="divTableCell"> <select name={{v.vartype}}> {% if v.vartype_value==1 %} <option value=1 selected> {% else %} <option value=1> {% endif %} Integer</option> {% if v.vartype_value==2 %} <option value=2 selected> {% else %} <option value=2> {% endif %} String</option> {% if v.vartype_value==3 %} <option value=3 selected> {% else %} <option value=3> {% endif %} Date</option> </select> </div> <div class="divTableCell"> <input type="text" name={{v.varformat}} {% if v.varformat_value %}value={{v.varformat_value}}{% endif %} class="vTextField" maxlength="20" > </div> </div> {% endfor %}
报错信息
[13/Jan/2023 08:23:12] "GET /static/admin/fonts/Roboto-Bold-webfont.woff HTTP/1.1" 200 86184 VARS:[{'field_id': 'ac9a3707-3906-4e75-9efd-514959056ddb', 'varname': 'varname_ac9a3707-3906-4e75-9efd-514959056ddb', 'varlabel': 'varlabel_ac9a3707-3906-4e75-9efd-514959056ddb', 'vartype': 'vartype_ac9a3707-3906-4e75-9efd-514959056ddb', 'varformat': 'varformat_ac9a3707-3906-4e75-9efd-514959056ddb', 'varname_value': 'kepada', 'varlabel_value': 'Kepada', 'vartype_value': 2, 'varformat_value': False}] Internal Server Error: /mst/htmx/get_schema/2 Traceback (most recent call last): File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/template/smartif.py", line 179, in translate_token op = OPERATORS[token] KeyError: 'v.vartype_value==1' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) File "/home/bino/Documents/dynform/htmx01/myapp/views.py", line 48, in mailtemplate_GetSchema return render(request, 'mailtemplate_all.html', {'vars': vars}) ... File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/template/smartif.py", line 181, in translate_token return self.create_var(token) File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/template/defaulttags.py", line 889, in create_var return TemplateLiteral(self.template_parser.compile_filter(value), value) File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/template/base.py", line 600, in compile_filter return FilterExpression(token, self) File "/home/bino/.venv/htmx01/lib/python3.10/site-packages/django/template/base.py", line 703, in __init__ raise TemplateSyntaxError( django.template.exceptions.TemplateSyntaxError: Could not parse the remainder: '==1' from 'v.vartype_value==1' [13/Jan/2023 08:23:12] "GET /mst/htmx/get_schema/2 HTTP/1.1" 500 200297 Not Found: /favicon.ico [13/Jan/2023 08:23:12] "GET /favicon.ico HTTP/1.1" 404 2212
测试情况
将视图输出的vars数据取出,使用Jinja2测试相同模板,渲染正常且输出符合预期:
(htmx01) bino@corobalap ~/Documents/dynform/htmx01 python3 Python 3.10.6 (main, Nov 14 2022, 16:10:14) [GCC 11.3.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from jinja2 import Template >>> vars=[{'field_id': 'ac9a3707-3906-4e75-9efd-514959056ddb', 'varname': 'varname_ac9a3707-3906-4e75-9efd-514959056ddb', 'varlabel': 'varlabel_ac9a3707-3906-4e75-9efd-514959056ddb', 'vartype': 'vartype_ac9a3707-3906-4e75-9efd-514959056ddb', 'varformat': 'varformat_ac9a3707-3906-4e75-9efd-514959056ddb', 'varname_value': 'kepada', 'varlabel_value': 'Kepada', 'vartype_value': 2, 'varformat_value': False}] >>> with open('myapp/templates/mailtemplate_all.html','r') as tfile: ... template = Template(tfile.read()) ... >>> o=template.render(vars=vars) >>> print(o) <div id=ac9a3707-3906-4e75-9efd-514959056ddb class="divTableRow"> <div class="divTableCell"> <input type="text" name=varname_ac9a3707-3906-4e75-9efd-514959056ddb value=kepada class="vTextField" maxlength="20" > </div> <div class="divTableCell"> <input type="text" name=varlabel_ac9a3707-3906-4e75-9efd-514959056ddb value=Kepada class="vTextField" maxlength="20" > </div> <div class="divTableCell"> <select name=vartype_ac9a3707-3906-4e75-9efd-514959056ddb> <option value=1> Integer</option> <option value=2 selected> String</option> <option value=3> Date</option> </select> </div> <div class="divTableCell"> <input type="text" name=varformat_ac9a3707-3906-4e75-9efd-514959056ddb class="vTextField" maxlength="20" > </div> </div> >>> >>>
问题原因与解决方案
视图代码本身没有问题,错误出在Django模板的比较语法规则上:Django要求比较运算符==的两边必须添加空格,不能像Jinja2那样直接写v.vartype_value==1,正确格式应为v.vartype_value == 1。
修改模板中的if条件语句,给==两边加上空格即可解决:
<select name={{v.vartype}}> {% if v.vartype_value == 1 %} <option value=1 selected> {% else %} <option value=1> {% endif %} Integer</option> {% if v.vartype_value == 2 %} <option value=2 selected> {% else %} <option value=2> {% endif %} String</option> {% if v.vartype_value == 3 %} <option value=3 selected> {% else %} <option value=3> {% endif %} Date</option> </select>
另外,也可以使用Django模板专属的{% ifequal %}标签替代==比较,写法如下:
{% ifequal v.vartype_value 1 %} <option value=1 selected> {% else %} <option value=1> {% endifequal %}
内容的提问来源于stack exchange,提问作者Bino Oetomo
相关产品推荐
相关产品推荐

