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.headers?HttpRequest.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 异步视图中存在多长时间