PUT和DELETE在Django中的应用

11

我相对于 Django 和 Python 来说比较新,最近几天一直在尝试弄清楚如何通过 Django 表单发送 PUT 和 DELETE 请求。

我找到了这些话题: https://baxeico.wordpress.com/2014/06/25/put-and-delete-http-requests-with-django-and-jquery/

Sending a DELETE request from a form in Django

但是,这些话题解决这个问题的方式对我来说似乎并不容易。所以问题是 - 是否有任何简单的方法可以通过 Django 表单发送 PUT 和 DELETE 请求。

目前我有这个:

views.py

class AllRoutes(View):

model = Schedule
template_name = 'trains_schedule/all_routes.html'

def get(self,request,train_id=None):
    if train_id:
        train = Schedule.objects.get(pk=int(train_id))
        context = {'train':train}
    else:
        context = {'schedule_list':Schedule.objects.all()}
    return render(request,'trains_schedule/all_routes.html',context)

def delete(self,request,train_id=None):
    route = get_object_or_404(Schedule, pk=train_id)
    response = u'Successful delete route {}'.format(route.display_name())
    route.delete()
    return HttpResponse(response)

urls.py

urlpatterns = [
url(r'^trains/(?P<train_id>[0-9]+)?$', views.AllRoutes.as_view(), name='trains')]

所有路线.html

{% if schedule_list %}
<h3>{{ "List of all train routes" }}</h3>
<ul>
{% for train_route in schedule_list %}
    <li><a href="{% url 'trains' train_route.id %}">{{ train_route.display_name }}</a></li>
{% endfor %}
</ul>
{% else %}
<p></p>
{% endif %}

{% if train %}
<h1>{{ train.train }}</h1>

<h3>{{ "Route info" }}</h3>
{{ train.display_train }}

<h3>{{ "Train info" }}</h3>
{{train.display_train_info}}

<form  method="delete">
{% csrf_token %}
<input type="submit" value="Delete" />
</form>
{% else %}
<p></p>
{% endif %}

现在它的工作方式如下:

  • /trains/ 显示所有火车路线的列表,并提供每条路线的链接
  • /trains/12 - get() 在 views.py 中获取路线 id 并显示有关该路线的信息

当我按下“删除”时,希望视图接收到 DELETE 请求。

最终我这样做:

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

在views.py中,我添加了对于action_id =="Delete"的POST请求的处理。

但是我想要真正的DELETE和PUT请求,而不是解析POST请求以理解我需要做什么 - 删除或更改路由或添加新路由。

我明白我需要更改这部分内容:

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

但是我不知道如何做到。


你是在询问如何在Django中正确地执行删除或编辑操作,还是想要实现一个合适的REST接口?答案会有所不同,如果是为了REST接口,最好使用第三方包。 - dkarchmer
我只想知道从前端发送PUT和DELETE请求的最简单方法是什么。我了解了REST框架,但仍然存在同样的问题 - 不知道如何从前端发送PUT和DELETE请求。 - Vova
它听起来像是您已经阅读过使用PUT和DELETE更改和删除数据的内容,但除非您正在开发API,否则可以直接使用适当的Django方式创建编辑和删除视图。因此,与其尝试使用您可能不理解的术语,不如解释一下您的最终目标。 - dkarchmer
好的,我来解释一下 - 我参加了一次实习开发者职位的面试,其中一个任务是创建 Django 服务,结果是 http://smosker.pythonanywhere.com/schedule/。我应该以 REST 的方式创建应用程序,但在前端,我应该使用纯 HTML - 但我无法弄清楚如何发送 PUT 和 DELETE 请求,并且只能使用带有隐藏值的 POST 表单请求来进行 PUT 和 DELETE 请求。但我的面试官告诉我应该用另一种方法来完成。 - Vova
纯HTML?不允许使用Javascript吗? - dkarchmer
据我了解,虽然允许使用Javascript,但他们声称可以在纯HTML上实现。我是否正确理解了这个话题https://dev59.com/cYvda4cB1Zd3GeqPXEa6,他们使用了Javascript?或者我应该如何使用Javascript来完成它? - Vova
1个回答

22
根据HTML标准,表单的有效方法为GETPOST。因此,您不能这样做:<form method="delete">。然而,Django可以正确处理“PUT”和“DELETE”(以及所有其他)HTTP方法。
from django.views.generic import View


class TestView(View):
    http_method_names = ['get', 'post', 'put', 'delete']

    def put(self, *args, **kwargs):
        print "Hello, i'm %s!" % self.request.method

    def delete(self, *args, **kwargs):
        print "Hello, i'm %s!" % self.request.method


Hello, i'm PUT!
[06/Apr/2016 23:44:51] "PUT /de/teacher/test/ HTTP/1.1"
Hello, i'm DELETE!
[06/Apr/2016 23:57:15] "DELETE /de/teacher/test/ HTTP/1.1"

您可以通过Ajax进行PUT和DELETE http调用。如果您需要在表单中使用它,可以进行一些变通:

<form action="{% url 'teacher:test' %}" method="post">
    {% csrf_token %}
    <input type="hidden" name="_method" value="delete">
    <input type="submit" value="Delete">
</form>


class TestView(View):
    http_method_names = ['get', 'post', 'put', 'delete']

    def dispatch(self, *args, **kwargs):
        method = self.request.POST.get('_method', '').lower()
        if method == 'put':
            return self.put(*args, **kwargs)
        if method == 'delete':
            return self.delete(*args, **kwargs)
        return super(TestView, self).dispatch(*args, **kwargs)

    def put(self, *args, **kwargs):
        print "Hello, i'm %s!" % self.request.POST.get('_method')

    def delete(self, *args, **kwargs):
        print "Hello, i'm %s!" % self.request.POST.get('_method')


Hello, i'm delete!
[07/Apr/2016 00:10:53] "POST /de/teacher/test/ HTTP/1.1"
Hello, i'm put!
[07/Apr/2016 00:10:31] "POST /de/teacher/test/ HTTP/1.1"

这不是真正的PUT,但您可以在表单和Ajax / API调用中使用相同的接口。


谢谢,所以我理解得正确——在纯HTML中没有发送PUT和DELETE请求的方法? - Vova
只是评论一下,这是我发现的限制特定视图的HTTP方法的方法。我有一个视图,我想允许某人进行GET、POST或DELETE操作,但不允许进行PUT或PATCH操作。 - whoisearth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接