You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

错误原因

  1. 上下文缺失关键变量:渲染log_form.html时,context字典中没有传入all_logs、b、e这些模板依赖的变量。Django模板找不到变量时,会直接将变量名作为字符串输出,导致tuple_check标签的items参数实际是字符串'all_logs',而传入的(key, value)是元组,元组与字符串执行in操作时触发类型错误。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 06:50:23