Django中render_to_string报TypeError错误的原因及解决方法问询
Django局部更新渲染HTML片段报错的原因及修复
问题描述
在Django视图中通过if request.is_ajax() and request.method == 'POST':判断AJAX请求,尝试返回两个HTML片段实现页面局部更新时,触发错误:
TypeError: 'in <string>' requires string as left operand, not tuple
报错定位在第二个render_to_string调用(渲染app/log_form.html模板)。
相关代码
视图代码
def change_status(request, id): if request.is_ajax() and request.method == 'POST': if request.POST.get('active') == 'true': # .......do stuff context = { 'active': '' } html = render_to_string('app/button.html', context,request=request) html2 = render_to_string('app/log_form.html', context,request=request) # 报错位置 return JsonResponse({'form': html}, {'form2': html2}) else: print("Fail") else: print("Fail")
自定义模板标签my_custom_tags.py
@register.simple_tag def tuple_check(items, key, value): return (key, value) in items
模板使用标签代码
{% tuple_check all_logs b.order e.name as item_check_result %} {% if item_check_result %} do something {% else %} do something else {% endif %}
生成all_logs的代码
all_logs=[] for i in active_session.log.values(): new_name=i['log_order'],i['log_exercise'] all_logs.append(new_name)
错误原因
- 上下文缺失关键变量:渲染
log_form.html时,context字典中没有传入all_logs、b、e这些模板依赖的变量。Django模板找不到变量时,会直接将变量名作为字符串输出,导致tuple_check标签的items参数实际是字符串'all_logs',而传入的(key, value)是元组,元组与字符串执行in操作时触发类型错误。 - JsonResponse参数错误:原代码中
JsonResponse传入了两个独立字典,不符合该方法的参数要求(仅接受一个字典作为序列化对象)。
修复步骤
1. 补充模板所需的上下文变量
在视图中生成all_logs并将所有模板依赖的变量加入context:
def change_status(request, id): if request.is_ajax() and request.method == 'POST': if request.POST.get('active') == 'true': # 原有业务逻辑代码 # 获取对应的active_session对象(需根据你的业务补充) active_session = # 例如:Session.objects.get(id=id) # 生成all_logs all_logs = [] for i in active_session.log.values(): new_name = (i['log_order'], i['log_exercise']) all_logs.append(new_name) # 补充所有模板需要的变量 context = { 'active': '', 'all_logs': all_logs, 'b': # 模板中用到的b对象,需根据业务获取 'e': # 模板中用到的e对象,需根据业务获取 } html = render_to_string('app/button.html', context, request=request) html2 = render_to_string('app/log_form.html', context, request=request) # 合并成单个字典传入JsonResponse return JsonResponse({'form': html, 'form2': html2}) else: print("Fail") else: print("Fail")
2. 优化自定义标签(可选)
给tuple_check标签增加类型校验,避免因参数类型错误触发异常:
@register.simple_tag def tuple_check(items, key, value): # 仅当items是列表或元组时才执行判断,否则返回False if not isinstance(items, (list, tuple)): return False return (key, value) in items
3. 修正JsonResponse调用
确保JsonResponse仅接收一个字典参数,将两个HTML片段放在同一个字典中返回。
内容的提问来源于stack exchange,提问作者A_K
相关产品推荐
相关产品推荐

