Delete multiple objects in django
Asked Answered
G

2

195

I need to select several objects to be deleted from my database in django using a webpage. There is no category to select from so I can't delete from all of them like that. Do I have to implement my own delete form and process it in django or does django have a way to already do this? As it's implemented in the admin interface.

Specifically, I need to select the objects to delete with a form on a webpage. And then process the data returned from the form in my views.py. Then loop through what's returned in the form deleting as it's looping through the data. But I wanted to know what is best practice for implementing this in django.

Gardant answered 4/2, 2012 at 18:24 Comment(0)
E
372

You can delete any QuerySet you'd like. For example, to delete all blog posts with some Post model

Post.objects.all().delete()

and to delete any Post with a future publication date

Post.objects.filter(pub_date__gt=datetime.now()).delete()

You do, however, need to come up with a way to narrow down your QuerySet. If you just want a view to delete a particular object, look into the delete generic view.

EDIT:

Sorry for the misunderstanding. I think the answer is somewhere between. To implement your own, combine ModelForms and generic views. Otherwise, look into 3rd party apps that provide similar functionality. In a related question, the recommendation was django-filter.

Equerry answered 4/2, 2012 at 18:34 Comment(6)
No you've misunderstood the question. I understand I can delete everything. But I need to select the objects to delete with a form on a webpage. And then process the data returned from the form in my views.py. Then loop through whats returned in the form deleting as its looping through the data. But I wanted to know what is best practice for implementing this in django.Gardant
Ah, my mistake! I would either use a third-party app, or generic views with ModelForms.Equerry
@Dean, take a look at that delete view. Or you can just write your own view... I mean ultimately you are probably receiving a list of PKs and calling delete on your model... MyModel.objects.filter(id__in=request.POST.getlist('delete_list')).delete() and I'm sure you want something to make sure a random person can't delete all objects in your DB by guessing PKs.Epanorthosis
@YujiTomita Could you write more of an answer to your comment as that is exactly the sort of thing which answers my question.Gardant
@Dean, it's tough to answer your question without understanding more about it. You just need to build a form that allows a user to select the correct delete criteria (whatever that may be - perhaps even an input box where one types an ID number... but probably more complex), build a view that responds to that form, perhaps performs validation (permissions), and then finally runs that filter(foo).delete() method.Epanorthosis
One of the reasons this doesn't come with the framework is the question of authorization for edits/deletion and other complexities mentioned by @YujiTomita. If you really need complex filtering, check out django-filtering and add a delete button that calls QuerySet.delete() if the user is authorized.Equerry
L
0

I need to select the objects to delete with a form on a webpage.

Since each object has a unique id, one way to select items to delete is using the id.

Following implements an example where a button on a webpage passes off the id of an object to delete which is processed in the view.py file in a POST request.

views.py

from django.shortcuts import render
from .models import MyModel

def myview(request):
    # initialize some data to delete
    if request.method == 'GET': MyModel(name='John Doe', score=83).save()

    # delete object with the id that was passed in the post request
    if request.method == 'POST':
        if 'delete' in request.POST:
            try:
                # id of the object to delete
                key = request.POST['delete']
                # delete that object
                MyModel.objects.get(id=key).delete()
            except MyModel.DoesNotExist:
                pass
    scores = MyModel.objects.all()
    return render(request, 'mypage.html', {'scores': scores})

models.py

from django.db import models
class MyModel(models.Model):
    name = models.CharField(max_length=50)
    score = models.IntegerField()

urls.py

from django.urls import path
from .views import myview

urlpatterns = [
    path('mypage/', myview, name='mypage')
]

templates/mypage.html

<form method='post' action={% url 'mypage' %}>
    {% csrf_token %}
    {% for person in scores %}
        {{ person.name }} {{ person.score }}
        {% comment %} to differentiate entries, use id {% endcomment %}
        <button name='delete', value="{{person.id}}">Delete</button><br>
    {% endfor %}
</form>

It creates a webpage that looks like the following and when the Delete button is clicked, the entry for "John Doe" is deleted.

ex

Latchkey answered 9/10, 2023 at 3:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.