Django >= 3.1 和 is_ajax

问题描述 投票:0回答:8

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

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

JsonResponse

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

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

django ajax
8个回答
32
投票

检查

HTTP_X_REQUESTED_WITH
标题

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

摘自 3.1 发行说明

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


8
投票

有趣的事情——引用的弃用简介只能让你成功一半。没有任何迹象表明如何“使用新的

HttpRequest.accepts
方法”来替换
HttpRequest.is_ajax
——弃用文本、文档和发行说明中都没有。

所以,这里是:

if request.accepts("application/json")

(至少这对我有用。)


7
投票

代替:

if request.is_ajax():

帮助了我:

if request.headers.get('x-requested-with') == 'XMLHttpRequest':

3
投票

结合这些建议适用于我们的用例......

def is_ajax(request: django.http.request.HttpRequest) -> bool:
    """
    https://stackoverflow.com/questions/63629935
    """
    return (
        request.headers.get('x-requested-with') == 'XMLHttpRequest'
        or request.accepts("application/json")
    )

然后将

request.is_ajax()
的所有实例替换为
is_ajax(request)


0
投票

您是否尝试过检查HttpRequest.headers
HttpRequest.is_ajax() 取决于 HTTP_X_REQUESTED_WITH 标头。
所以你可以检查这个标头,如果它是真的,那么它将是 AJAX,否则它将是来自浏览器的请求。

HttpRequest.headers['HTTP_X_REQUESTED_WITH']

0
投票

我按照 arakkal-abu 所说的做了,但我还添加了

'X-Requested-With'
具有相同值的标头 IE。
'XMLHttpRequest'

按照我的要求,它成功了


0
投票

确保在顶部导入它

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

在 header 中,那么请求的 headers 就变成这样

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


0
投票

your_app.middleware.py

class AjaxMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        def is_ajax(self) -> bool:
            return (
                request.headers.get('x-requested-with') == 'XMLHttpRequest'
                or request.accepts("application/json")
            )
        
        request.is_ajax = is_ajax.__get__(request)
        response = self.get_response(request)
        return response

设置.py

MIDDLEWARE = [
    'your_app.middleware.AjaxMiddleware',
]
© www.soinside.com 2019 - 2024. All rights reserved.