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

Django中Ajax请求视图里return render(...)无法跳转页面的问题

问题:点击按钮创建聊天室后无法跳转至聊天页面

点击页面按钮调用Ajax请求创建聊天室,后台已成功生成Thread记录,但视图中return render(request, 'chat/chatroom.html')无法打开目标页面,无任何报错信息。

相关代码

HTML代码

<button type="submit" id="chat-button" value="{{advertisement.author.id}}">Write to the author</button>

<script>
    $(document).on('click', '#chat-button', function (e) {
    e.preventDefault();
    $.ajax({
      type: 'POST',
      url: '{% url "main_app:create-chat" %}',
      data: {
        send_to_id: $('#chat-button').val(),
        csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
        action: 'post'
      },
      success: function (json) {
      },
      error: function (xhr, errmsg, err) {
      }
    });
  })
</script>

views.py代码

from django.contrib.auth import get_user_model
from django.shortcuts import render, redirect, get_object_or_404
from django.db.models import Q
from django.utils.decorators import method_decorator
from django.views import View
from django.views.decorators.csrf import csrf_exempt

from chat.models import Thread

User = get_user_model()


@method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):

    def post(self, request):
        send_to_id = int(request.POST.get('send_to_id'))
        send_to = User.objects.get(id=send_to_id)
        auth_user = request.user
        final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) \
                  | Q(Q(first_person=auth_user) & Q(second_person=send_to))
        thread = Thread.objects.filter(final_q)
        if not thread:
            Thread.objects.create(first_person=auth_user, second_person=send_to)

        return render(request, 'chat/chatroom.html')

urls.py代码

app_name = 'main_app'

urlpatterns = [
    ...
    path('create_chat', CreateChat.as_view(), name='create-chat')
]

问题原因

Ajax是异步HTTP请求,服务器返回的HTML内容只会传递到success回调函数中,浏览器不会自动加载该内容作为新页面——它仅在后台接收数据,不会主动替换当前页面或发起跳转。因此你当前的写法中,视图返回的chatroom.html内容只是被Ajax接收,但未做任何处理,自然看不到页面跳转效果。


解决方案

方案1:调整Ajax逻辑,处理返回结果实现跳转

方式A:视图返回聊天室URL,前端主动跳转

修改views.py,创建Thread后返回该聊天室的访问URL:

from django.http import JsonResponse

@method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):
    def post(self, request):
        send_to_id = int(request.POST.get('send_to_id'))
        send_to = User.objects.get(id=send_to_id)
        auth_user = request.user
        final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) | Q(Q(first_person=auth_user) & Q(second_person=send_to))
        # 用first()获取单个对象,避免返回QuerySet
        thread = Thread.objects.filter(final_q).first()
        if not thread:
            thread = Thread.objects.create(first_person=auth_user, second_person=send_to)
        
        # 假设聊天室页面的URL格式为/chat/<thread_id>/,根据实际路由调整
        chat_url = f'/chat/{thread.id}/'
        return JsonResponse({'chat_url': chat_url})

修改前端JS,在success回调中跳转到返回的URL:

$(document).on('click', '#chat-button', function (e) {
    e.preventDefault();
    $.ajax({
      type: 'POST',
      url: '{% url "main_app:create-chat" %}',
      data: {
        send_to_id: $('#chat-button').val(),
        csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val(),
        action: 'post'
      },
      success: function (json) {
          // 跳转到聊天室页面
          window.location.href = json.chat_url;
      },
      error: function (xhr, errmsg, err) {
          console.error(errmsg); // 打印错误信息便于调试
      }
    });
})

方式B:用返回的HTML替换当前页面内容(仅适用于局部刷新场景)

如果不需要跳转页面,而是替换当前页面的部分内容,可以在success回调中处理返回的HTML:

success: function(response) {
    // 替换整个页面body内容
    $('body').html(response);
    // 或替换指定容器,比如页面中有<div id="chat-container"></div>
    // $('#chat-container').html(response);
}

方案2:放弃Ajax,使用普通表单提交(更简洁)

如果需求仅为创建聊天室后跳转页面,完全可以不用Ajax,直接用表单提交,服务器的redirect或render会直接生效:

修改HTML,将按钮包裹在表单中:

<form method="POST" action="{% url 'main_app:create-chat' %}">
    {% csrf_token %}
    <input type="hidden" name="send_to_id" value="{{advertisement.author.id}}">
    <button type="submit" id="chat-button">Write to the author</button>
</form>

修改views.py,创建Thread后跳转至聊天室页面(推荐用redirect,符合HTTP规范):

from django.shortcuts import redirect

@method_decorator(csrf_exempt, name='dispatch')
class CreateChat(View):
    def post(self, request):
        send_to_id = int(request.POST.get('send_to_id'))
        send_to = User.objects.get(id=send_to_id)
        auth_user = request.user
        final_q = Q(Q(first_person=send_to) & Q(second_person=auth_user)) | Q(Q(first_person=auth_user) & Q(second_person=send_to))
        thread = Thread.objects.filter(final_q).first()
        if not thread:
            thread = Thread.objects.create(first_person=auth_user, second_person=send_to)
        
        // 假设聊天室页面的URL名称为'chat:room',需传递thread.id参数,根据实际路由调整
        return redirect('chat:room', thread_id=thread.id)
        // 若需直接渲染页面,也可保留return render,但redirect更推荐
        // return render(request, 'chat/chatroom.html', {'thread': thread})

内容的提问来源于stack exchange,提问作者Dmytro

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:40:23