Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django - how to delete an object using a view

I have the class People

class People (models.Model):
    first_name = models.CharField(max_length = 50)
    last_name = models.CharField(max_length = 50)
    email = models.EmailField(blank = True)
    grade = models.CharField(max_length = 2)

    def __unicode__(self):
        return '%s %s' % (self.first_name, self.last_name)

I have the delete view

def delete(request):
    query = People.objects.get(pk=id)
    query.delete()
    return HttpResponse("Deleted!")

And I have the html template code

{% for person in people_list %}
<TR ALIGN="CENTER">
        <td>{{ person.first_name }}</td>
    <td>{{ person.last_name }}</td>
    <td>{{ person.email }}</td>
    <td>{{ person.grade }}</td>
    <td><form action="/modify.html">
        <input type="submit" value="Modify">
        </form></td>
    <td><form action="/delete.html">
        <input type="submit" value="Delete">
        </form></td>
</TR>
      {% endfor %}

How can I get the person.id from the template and put it in the delete view and delete the object corresponding with the person.id I want.

like image 996
Sarb Daniel Avatar asked Nov 03 '13 14:11

Sarb Daniel


3 Answers

You need to have your delete function(btw, name it something else, like delete_person) take in an argument, pk.

def delete_person(request, pk):
    ...
    ...

Then in your urlconf, do something like this

url(r'^delete_person/(?P<pk>\d+)/$', 'delete_person', name='delete_person')

And then generate the url in the template like so

{% url 'delete-person' person.id %}

PS - No need to have your urls end with .html

PPS - Would be a good idea to do some validation in the view to make sure that the user is authorized to delete the person.

like image 133
elssar Avatar answered Sep 21 '22 12:09

elssar


I think you could use a link instead of form:

Replace this line

<td>
  <form action="/delete.html">
    <input type="submit" value="Delete">
  </form>
</td>

with this

<td><a href="/delete/{{ person.id }}">Delete</a></td>

In urls.py you should add the following line to relate your view with url:

url(r'^delete/(?P<person_pk>.*)$', 'person.views.delete' name='delete-person'),

Then change your view:

def delete(request, person_pk):
    query = People.objects.get(pk=person_pk)
    query.delete()
    return HttpResponse("Deleted!")
like image 29
scriptmonster Avatar answered Sep 21 '22 12:09

scriptmonster


To expand on @scriptmonster, I wrapped the query in a try except to properly return a 404

# urls.py
path("foo/<int:pk>/", views.ModelView.as_view(), name="foo-detail"),$                                     

and

# views.py
from django.http import HttpResponse, HttpResponseNotFound                                               

class ModelView(View):                                                                                             
    model = Foo                                                                                                                                                                                                                                                     

    def delete(self, request, *args, **kwargs):                                                                       
        foo_id = kwargs["pk"]                                                                                      
        try:                                                                                                          
            query = Foo.objects.get(pk=foo_id)                                                                  
            query.delete()                                                                                            
            return HttpResponse("Deleted!")                                                                           
        except:                                                                                                       
            return HttpResponseNotFound()   
like image 22
Harry Moreno Avatar answered Sep 22 '22 12:09

Harry Moreno