Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PUT and DELETE Django

Tags:

python

django

I relatively new in django and python and now for a couple of days i'm trying to figure how to send PUT and DELETE requests throught django forms.

I found this topics: 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

But the way this topics solve this problem seams not easy for me. So question is - is there are any easy way to send PUT and DELETE requests throught forms in Django.

For now i have this:

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')]

all_routes.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 %}

Now it works this way:

  • /trains/ show list of all trains routes and provide links to every route
  • /trains/12 - get() in views.py got route id and show information about this route

And i want that when i pressing "delete" - view receive DELETE request.

I end with doing it this way:

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

and in views.py i add handling of post request with action_id =="Delete"

But i want to make real DELETE and PUT request, not parse the POST request to understand that i need to do - delete or change route or add new one.

I understand that i need to change this part:

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

But i dont know how to do it.

like image 904
Vova Avatar asked Apr 06 '16 15:04

Vova


1 Answers

According to the HTML standard, the valid methods for form are GET and POST. So you can't do like this <form method="delete">. However Django correct handle 'PUT' and 'DELETE' (and all others) http methods.

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"

You can make PUT and DELETE http calls thought the ajax. If you need to use it form you can do some workaround:

<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"

It's not the real PUT but you can use the same interface for forms and ajax/api calls.

like image 153
crash843 Avatar answered Nov 15 '22 19:11

crash843