gpt4 book ai didi

jquery - 从 Django 中的表单发送 DELETE 请求

转载 作者:行者123 更新时间:2023-12-03 23:06:46 25 4
gpt4 key购买 nike

我正在尝试从 Django 中的表单发送 DELETE 请求,并引用下面的链接获取 jQuery 的帮助;

https://baxeico.wordpress.com/2014/06/25/put-and-delete-http-requests-with-django-and-jquery/

我拥有以下脚本;

<script src="jquery-1.11.3.js"></script>

<script>
$(document).ready(function(){
$.ajax({
id : 'delete',
headers : {'X_METHODOVERRIDE': 'DELETE'}
});
});
</script>

(我打算)按照以下表格行事;

<form method="post" id="delete" name="delete" action="">
{% csrf_token %}
<input type="submit" value="Delete" />
</form>

以及以下中间件;

from django.http import QueryDict

class HttpPostTunnelingMiddleware(object):
def process_request(self, request):
if request.META.has_key('HTTP_X_METHODOVERRIDE'):
http_method = request.META['HTTP_X_METHODOVERRIDE']
if http_method.lower() == 'put':
request.method = 'PUT'
request.META['REQUEST_METHOD'] = 'PUT'
request.PUT = QueryDict(request.body)
if http_method.lower() == 'delete':
request.method = 'DELETE'
request.META['REQUEST_METHOD'] = 'DELETE'
request.DELETE = QueryDict(request.body)
return None

我已将其添加到我的 settings.py 中的 MIDDLEWARE_CLASSES 列表中;

MIDDLEWARE_CLASSES = (
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'stationrunner.middleware.HttpPostTunnelingMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
)

这是第三个条目,在 CsrfViewMiddleware 考虑 @Daniel Roseman 的话之前。

最后在我的基于类的 View 中,我有删除方法删除相应的对象;

class StationHome(View):
.
.
.
def post(self,request, pk):
station = Station.objects.get(pk=pk)
form = StationForm(request.POST, instance=station)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse("home_station",
kwargs={'pk':pk},
)
)
else:
return HttpResponse("Form Invalid!")

def delete(self, request, pk):
Station.objects.get(pk=pk).delete()
return HttpResponseRedirect(
reverse("list_create_station")
)
.
.

我希望中间件和脚本向 View 发送一个 DELETE 请求,但事情并没有发生。正在发送 POST 方法本身。 Django 发现一个无效的表单并给了我响应; “表格无效!” (else: return HttpResponse("表单无效!")

更新

我已将脚本更新为如下所示;

<script>
$(document).ready(function(){
$('#delete').submit.function(e){
e.preventDefault();
var station_id = {{ station.id }}
$.ajax({
type: 'POST',
url: '/station/' + station_id,
headers: {'X_METHODOVERRIDE': 'DELETE'}
});
});
});
</script>

我将对象作为 station 传递给模板,并且在脚本中使用了 Django 模板语言 (var station_id = {{ station.id }})从 https://stackoverflow.com/a/6008968/4672736 获取灵感

结果是一样的:/

更新

调试js发现浏览器没有找到jQuery文件。现在,静态文件已正确配置,并且在 jquery.cookie.js 的帮助下设置了 csrf 保护,我的模板中包含以下代码;

<script src="{% static "stationrunner/jquery-1.11.3.js" %}"></script>
<script src="{% static "stationrunner/jquery.cookie.js" %}"></script>

<script>
$(document).ready(function(){
var csrftoken = $.cookie('csrftoken');
function csrfSafeMethod(method) {
// these HTTP methods don't require CSRF protection
return(/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if(!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
});
$('#delete').submit(function(e){
e.preventDefault();
$.ajax({
type: 'POST',
url: '{% url 'home_station' station.id %}',
headers: {'X_METHODOVERRIDE': 'DELETE'}
});
});
});
</script>

现在我的前端没有错误,但还没有成功。提交表单后我得到了 200 响应,而不是 302

这是 AJAX 请求所期望的吗?

看来该请求尚未作为删除请求传递到 View 。

我尝试将 success: function(){alert('Object returned!')} 添加到 $.ajax 中,并且确实弹出了警报。

更新

最后一个障碍是我必须在传递的自定义 header 中使用破折号而不是下划线。我将 headers: { 'X_METHODOVERRIDE': 'DELETE' } 更改为 headers: { 'X-METHODOVERRIDE': 'DELETE' }。这些字母也不必以大写字母传递。无论如何,Django 都会将它们转换为大写字母。因此,x-methodoverride 或 x-MeThODoveRrIDE 也可以。我不知道为什么用破折号而不是下划线。我发现传递的其他 header 带有破折号而不是下划线。

早些时候,中间件未找到 key HTTP_X_METHODOVERRIDE。现在它出现了,我的 View 收到了删除请求:)

最佳答案

问题出在您的 JavaScript 代码上。您将表单作为常规 POST 请求提交,根本不使用 $.ajax javascript 代码。

您应该将 jquery 包含在单独的脚本标记中,如下所示:

<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>

然后在另一个脚本标记中放置代码:

<script>
$('#delete').submit(function(e) {
// do NOT submit the form as a regular POST request
e.preventDefault();
var object_to_delete_id = $('#object_to_delete_id').val();
$.ajax({
type: 'POST',
url: '/your-view-url/' + object_to_delete_id,
success: function() {
alert('Object deleted!')
},
headers: { 'X_METHODOVERRIDE': 'DELETE' }
});
});
<script>

这里我假设您在表单字段中拥有要删除的对象的 ID,如下所示:

<form method="post" id="delete" name="delete" action="">
{% csrf_token %}
<input type="text" id="object_to_delete_id" />
<input type="submit" value="Delete" />
</form>

请注意 Ajax 调用上的 Django CSRF 保护,您应该编写一些 javascript 来在请求中设置 CSRF cookie 值,如 Django documentation 中所述。 .

同时将 HttpResponseRedirect 返回到 Ajax 调用没有多大意义,因为浏览器不会像常规 POST 请求那样重定向到该页面。

我建议在深入研究像这样的更复杂的示例之前,先多研究一下 jquery 和 Ajax 请求的工作原理。 ;)

关于jquery - 从 Django 中的表单发送 DELETE 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30461839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com