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

Django+jQuery发送POST请求后DIV内messages数据和页面无法更新问题

问题核心原因

  • 你之前load方法失效的核心原因:该方法会发起全新的GET请求拉取当前页面,请求没有携带你选中的userId参数,服务端返回的还是默认第一个用户的消息,自然不会更新为你选中用户的内容。
  • 按钮点击的POST请求默认没有携带Django要求的CSRF令牌,也是潜在的请求失效原因。

方案1:最优解-局部只更新消息区域

不需要刷新整个页面,只返回消息渲染片段替换即可,性能最优。

步骤1:拆分消息模板

把消息循环的代码单独抽成一个子模板,存为templates/_chat_messages.html:

{% for o in messages %}
{% if o.to_id.id != 2 %}
<div class="d-flex justify-content-start mb-4">
  <div class="img_cont_msg">
    <!-- 原有图片内容 -->
  </div>
  <div class="msg_cotainer">
    {{o.message}} 
    <!-- <span class="msg_time">{{o.time}}</span> -->
  </div>
</div>
{% else %}
<div class="d-flex justify-content-end mb-4">
  <div class="msg_cotainer_send">
    {{o.message}}
    <!-- <span class="msg_time_send">{{o.time}}</span> -->
  </div>
  <div class="img_cont_msg">
    <!-- 原有图片内容 -->
  </div>
</div>
{% endif %}
{% endfor %}

主页面psych.html中原来放消息循环的位置,替换为引入子模板的代码,确保外层有id为messageDiv的容器:

<div id="messageDiv">
{% include '_chat_messages.html' %}
</div>

步骤2:修改后端视图

判断是AJAX请求时,只返回消息片段,不用渲染整个页面:

def your_view(request):
    m = Message.objects.filter(to_id=2).order_by('-id')
    users = {}
    for i in m:
        if users.get(i.from_id.username) == None:
            users[i.from_id.username] = User.objects.get(id=i.from_id.id)
    users = list(users.values())
    default_user_id = users[0].id if users else None

    if request.method == 'POST':
        user_id = request.POST.get('userId')
        send=Message.objects.filter(from_id=user_id,to_id=2)
        rec=Message.objects.filter(from_id=2,to_id=user_id)
        messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
        # 识别AJAX请求则只返回消息片段
        if request.is_ajax():
            return render(request, '_chat_messages.html', {"messages": messages})
        return render(request,'psych.html',{"users":users, "messages":list(messages)})
    
    # GET请求走原有逻辑
    send=Message.objects.filter(from_id=default_user_id,to_id=2)
    rec=Message.objects.filter(from_id=2,to_id=default_user_id)
    messages=sorted(chain(rec, send),key=lambda instance: instance.id,reverse=True)
    return render(request,'psych.html',{"users":users, "messages":list(messages)})

步骤3:修改前端JS代码

先全局配置CSRF令牌,再直接替换消息区域内容:

// 全局配置CSRF,避免每次请求单独传参
function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}
const csrftoken = getCookie('csrftoken');
$.ajaxSetup({
    headers: {
        'X-CSRFToken': csrftoken
    }
});

// 点击用户按钮的请求逻辑
function newUser(id){
    $.ajax({
        type: 'POST',
        url:'/psych.html/',
        data:{
            userId:id,
        },
        success: function(data){
            // 直接用返回的消息片段替换原有内容
            $('#messageDiv').html(data);
        }
    })
}

方案2:整页替换方案

如果不想改模板结构,直接用服务端返回的完整页面替换当前页面内容即可,修改newUser的success回调:

function newUser(id){
    $.ajax({
        type: 'POST',
        url:'/psych.html/',
        data:{
            userId:id,
            csrfmiddlewaretoken: getCookie('csrftoken')
        },
        success: function(data){
            // 直接替换整个页面的HTML内容
            document.documentElement.innerHTML = data;
            // 如果只需要替换正文区域也可以写:$('body').html(data);
        }
    })
}

内容的提问来源于stack exchange,提问作者مهند حجي

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 19:57:00