HttpRequest.is_ajax()
从版本 3.1 开始已弃用。
如果从浏览器请求页面,我想返回 html;如果从 javascript 或以编程方式调用页面,则返回
JsonResponse
。
我正在寻求如何做到这一点的指导。
https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.HttpRequest.is_ajax
检查
HTTP_X_REQUESTED_WITH
标题
def sample_view(request):
is_ajax = request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
摘自 3.1 发行说明
方法已被弃用,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前的使用倾向于使用 JavaScript Fetch API。根据您的用例,您可以编写自己的 AJAX 检测方法,或者如果您的代码依赖于客户端 Accept HTTP 标头,则可以使用新的HttpRequest.is_ajax()
方法。HttpRequest.accepts()
有趣的事情——引用的弃用简介只能让你成功一半。没有任何迹象表明如何“使用新的
HttpRequest.accepts
方法”来替换HttpRequest.is_ajax
——弃用文本、文档和发行说明中都没有。
所以,这里是:
if request.accepts("application/json")
(至少这对我有用。)
代替:
if request.is_ajax():
帮助了我:
if request.headers.get('x-requested-with') == 'XMLHttpRequest':
结合这些建议适用于我们的用例......
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)
。
您是否尝试过检查HttpRequest.headers?
HttpRequest.is_ajax() 取决于 HTTP_X_REQUESTED_WITH 标头。
所以你可以检查这个标头,如果它是真的,那么它将是 AJAX,否则它将是来自浏览器的请求。
HttpRequest.headers['HTTP_X_REQUESTED_WITH']
我按照 arakkal-abu 所说的做了,但我还添加了
'X-Requested-With'
具有相同值的标头
IE。 'XMLHttpRequest'
按照我的要求,它成功了
确保在顶部导入它
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 就变成这样
由此,您可以了解这些情况下接受标头有何不同。
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
MIDDLEWARE = [
'your_app.middleware.AjaxMiddleware',
]