Django - how to delete an object using a view

17,684

Solution 1

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.

Solution 2

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

Solution 3

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()   
Share:
17,684
Sarb Daniel
Author by

Sarb Daniel

Updated on June 08, 2022

Comments

  • Sarb Daniel
    Sarb Daniel almost 2 years

    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.

  • shan.B
    shan.B over 10 years
    You're my man! Our answers are has differences but the way is nearly identical. :)
  • Daniel Roseman
    Daniel Roseman over 10 years
    That's a very bad idea. Actions that modify the database shouldn't be called with GET.
  • Sarb Daniel
    Sarb Daniel over 10 years
    I want to do just a simple project app
  • shan.B
    shan.B over 10 years
    @DanielRoseman I don't think so, if you make required controls within your view, it doesn't matter if it is get, post, delete or whatever. Since I can simulate all types of requests, all http requests are vulnerable at same level.
  • elssar
    elssar over 10 years
    @DanielRoseman unless the csrf_middleware is being used, wouldn't it be the same whether you use POST or GET? Though yes I agree that either a POST or an ajax PUT or DELETE request should be used to modify database objects.
  • NathanOliver
    NathanOliver over 4 years
    While this code may solve the problem the answer would be a lot better with an explanation on how/why it does. Remember that your answer is not just for the user that asked the question but also for all the other people that find it.