Django >= 3.1 和 is_ajax

Posted

技术标签:

【中文标题】Django >= 3.1 和 is_ajax【英文标题】:Django >= 3.1 and is_ajax 【发布时间】:2020-12-17 03:51:16 【问题描述】:

HttpRequest.is_ajax() 从 3.1 版开始已弃用。

如果页面是从浏览器请求的,我想返回 html,如果从 javascript 或以编程方式调用,我想返回 JsonResponse

我正在寻求有关如何做到这一点的指导。

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

【问题讨论】:

它已被弃用,但尚未移除 【参考方案1】:

检查HTTP_X_REQUESTED_WITH标头

def sample_view(request):
    is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'

来自Release Notes of 3.1

HttpRequest.is_ajax() 方法已被弃用,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前使用倾向于使用 JavaScript Fetch API。根据您的用例,您可以编写自己的 AJAX 检测方法,或者如果您的代码依赖于客户端 Accept HTTP 标头,则使用新的 HttpRequest.accepts() 方法。

【讨论】:

【参考方案2】:

有趣的是——无论是弃用消息、文档还是发行说明,都没有说明您“如何使用新的HttpRequest.accepts 方法”来替换HttpRequest.is_ajax

TLDR:request.accepts("application/json")

(至少这对我有用。)

【讨论】:

【参考方案3】:

您是否尝试过检查 HttpRequest.headersHttpRequest.is_ajax() 取决于 HTTP_X_REQUESTED_WITH 标头。 因此您可以检查此标头,如果为真,则为 AJAX,否则为来自浏览器的请求。

HttpRequest.headers['HTTP_X_REQUESTED_WITH']

【讨论】:

【参考方案4】:

我按照 arakkal-abu 所说的做了,但我也添加了 'X-Requested-With' 具有相同值的标头 IE。 'XMLHttpRequest'

按照我的要求,它成功了

【讨论】:

【参考方案5】:

确保在顶部导入它

import re
from django.http import JsonResponse
from django.utils.translation import gettext_lazy as _
from django.conf.urls import handler404

您可以在您的函数/方法中使用它来确定是来自浏览器还是 ajax 调用

    requested_html = re.search(r'^text/html', request.META.get('HTTP_ACCEPT'))
    if requested_html:
        # requested from browser, do as per your wish
    # ajax call. Returning as per wish 
    return JsonResponse(
        'detail': _('Requested API URL not found')
    , status=404, safe=False)

说明

如果您请求从浏览器加载页面,您会在该请求的请求标头下的网络选项卡中看到,text/html 位于 requested headers 的开头。

但是,如果您从浏览器进行 ajax 调用,requested headers 的开头有 */*。如果你附上

Accept: application/json

在标头中,然后请求的标头变成这个

由此,您可以了解这些情况下接受标头的不同之处。

【讨论】:

【参考方案6】:

只需检查Content-Type 标头。

is_ajax = request.META.get("CONTENT_TYPE") == "application/json"
if is_ajax:
    do_stuff()

【讨论】:

以上是关于Django >= 3.1 和 is_ajax的主要内容,如果未能解决你的问题,请参考以下文章

event_loop 在 Django>=3.1 异步视图中存在多长时间

Django

django系列3.1--url的命名和反向解析

Django 3.1:带有异步生成器的 StreamingHttpResponse

Django初识

Django新版本3.1,设置文件有一些变化