如何使用 AJAX 刷新 Django 页面的一部分?

Posted

技术标签:

【中文标题】如何使用 AJAX 刷新 Django 页面的一部分?【英文标题】:How to refresh part of a Django page with AJAX? 【发布时间】:2019-12-23 23:27:02 【问题描述】:

我正在使用 Django 部署一个网站。有一个名为“论坛”的应用程序,支持我网站上的讨论论坛。

论坛的网址是“XXX.com/forum/roomY”。当用户单击刷新按钮时,我想在此页面上刷新包含消息列表的 div id = ''chat''。我想使用 AJAX 来做到这一点。

但我发现我无法调用函数 updatestatementlist(request) 来检索更新后的消息列表,因此可以将其传递到此页面上。

/forum/views.py def updatestatementlist(request):

log.debug("call statementlist function")
statements = Statement.objects.filter(discussion=discussion)
return render(request, 'forum/statementlist.html', 
    'statements': statements
    )

我看不到日志信息,所以我认为通过单击按钮我无法调用此函数。

论坛的主html页面是/forum/discussion.html,在模板文件夹下。我将 div id = "chat" 中的 html 代码提取到单独的 html /forum/statementlist.html 建议 here 和其他几个 SO 帖子。

/forum/discussion.html

<button id = "Refresh"> Refresh </button>
<div id="chat">
% include 'forum/statementlist.html' %
</div>

/forum/statementlist.html

% load mptt_tags %
% recursetree statements %
    // display each statement
% endrecursetree %

forum.js

//When users click the refresh button
    $("#Refresh").on("click", function(event)
    alert("Refresh clicked")
    $.ajax(
        url: '',
        type: "GET",
        success: function(data) 
            alert("success")
            var html = $(data).filter('#chat').html();
            $('#chat').html(html);
        
    );
);

我还在此 AJAX 请求中尝试了其他一些 url:% url updatestatementlist %、% url 'updatestatementlist' %。但后来我认为它应该设置为空,因为我不想被重定向到另一个 url。论坛有一个 'XXX.com/forum/roomY' 的 url,通过单击此页面上的刷新按钮,我只想刷新 div 并从服务器获取更新的语句列表。

顺便说一句,单击按钮后我可以看到两个警报。

/forum/urls.py

urlpatterns = [
...
url(r'^(?P<label>[\w-],50)/$', views.discussion_forum, name='discussion_forum'),
url(r'^(?P<label>[\w-],50)/$', views.statementlist, name='statementlist'),

]

/forum/views.py def discussion_forum() 用于加载用户第一次到达该论坛时的所有信息。

我想我的问题可能是 1) AJAX 错误; 2) url错误,导致无法调用updatestatementlist()。

谁能帮我解决这个问题?非常感谢!如果您需要任何其他信息,请告诉我!

相关包:

Django==1.9.3

django-mptt==0.8.7

【问题讨论】:

【参考方案1】:

在客户端,将你的请求头设置为X-Requested-WithXMLHttpRequest,Django使用这个特定的头来判断它是否是一个Ajax请求:

这是来自 Django 源代码的 sn-p: https://docs.djangoproject.com/en/2.2/_modules/django/http/request/#HttpRequest.is_ajax

def is_ajax(self):
    return self.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

定义完这个header后,你需要在你的视图函数中添加一个逻辑层。

def your_view_func(request, *args, **kwargs):
    if request.is_ajax():
        ...
        return render(request, <your_ajax_template>)
    return render(request, <your_normal_template>)

更新

我更喜欢原始的XMLHttpRequest API,如果您使用Jquery,请添加berforeSend 属性。

$.ajax(
  type: "GET",
  beforeSend: function(request) 
    request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
  ,
  ...
);

为什么是 X-Requested-With 而不是 HTTP_X_REQUESTED_WITH?

请求中的 HTTP 标头通过将所有字符转换为大写、用下划线替换任何连字符并在名称中添加 HTTP_ prefix 来转换为 META 键。

https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.HttpRequest.META

【讨论】:

您能否更具体地了解如何编写 ajax?谢谢。我是 javascript 新手。 谢谢。我添加了 beforeSend 属性,但我仍然认为通过按下刷新按钮我无法将 ajax 请求发送到 views.py/updatestatementlist()。因为在 updatestatementlist 中我有两个分支:if 或 else request.is_ajax()。没有显示来自两个分支的日志信息。可能是我的网址格式错误? 我不会对AJAX请求使用include标签,它只在页面加载时加载一次,尝试使用Django JsonResponse取回JSON数据,然后动态添加html数据通过将onclick 事件注册到您的元素。

以上是关于如何使用 AJAX 刷新 Django 页面的一部分?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Django、Ajax、jQuery 在不刷新页面的情况下提交表单?

如何在jquery ajax之后刷新网站的一部分而不刷新整个页面

使用AJAX获取Django后端数据

Django使用Ajax实现页面无刷新评论回复功能

js界面刷新&Django使用Ajax实现页面无刷新评论回复功能

使用 jquery、ajax 和 django 定期刷新页面