3

Is it possible to delete many Model instances without iterating over them and calling .delete() on each one?

Let's say we have something like this:

objects = [o for o in MyObject.objects.filter(...)]

objects_to_delete = get_validate_objects(objects) # some of objects from objects

And now I want to delete every MyObject in objects_to_delete. Is there any better/smarter way than this?:

for o in objects_to_delete:
    o.delete()

Also I want to be sure that all objects were deleted. Exception/message about problem during deleting object (deleted earlier) will be nice.

4
  • refer stackoverflow.com/questions/9143262/… Commented Oct 16, 2019 at 11:43
  • You could customize your Manager class, such that MyObject.valid_objects already returns a filterset with custom filter semantics, and then just objects.delete() them Commented Oct 16, 2019 at 11:45
  • I reopened this because the linked question is slightly different and the single answer doesn't answer this. Commented Oct 16, 2019 at 11:47
  • Possible duplicate of Delete multiple objects in django Commented Oct 16, 2019 at 11:52

2 Answers 2

6

You can delete a queryset; to get a queryset containing the objects you have in a list you could do:

objects_to_delete = MyObject.objects.filter(pk__in=[o.pk for o in objects])
objects_to_delete.delete()

But ideally you would write "get_validate_objects" in such a way that it took a queryset as parameter and did all its checks on the queryset (using filter() and exclude() and the like). Then you could call .delete() on the result immediately. But that isn't always easy, of course.

Sign up to request clarification or add additional context in comments.

3 Comments

I got it. But it not resolved problem where object in pk__in was deleted earlier. No message or exception. I can only compare list of deleted ids to numer of deleted objects.
@kedod: that's a more fundamental problem, database software does not give you an error if you use a DELETE SQL statement with an IN clause where not all the ids in there match with some row in the table. So you won't get an error from that, it is OK as far as relational databases are concerned.
Also, what are you doing that makes it possible they are already deleted, and why does it matter if they are already?
3

Since you have objects in objects_to_delete, you can get the ids of those objects and delete. Do something like:

MyObject.objects.filter(id__in=[i.id for i in objects_to_delete]).delete()

It will result in the following SQL.

DELETE FROM MyObject WHERE id IN (ids of objects)

For e.g. if the id's of the objects to be deleted are 1,2, 3, 4, 5 then the sql will be:

DELETE FROM MyObject WHERE id IN (1, 2, 3, 4, 5)

1 Comment

I got it. But it not resolved problem where object in pk__in was deleted earlier. No message or exception. I can only compare list of deleted ids to numer of deleted objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.