Disabling .delete() in querysets in Django

55 views
Skip to first unread message

אורי

unread,
May 20, 2020, 8:57:08 AM5/20/20
to Django developers (Contributions to Django itself)
Django developers,

I recently disabled .delete() in querysets in all managers in my project, after encountering a bug in a bulk delete queryset in my tests [https://code.djangoproject.com/ticket/31600]. Actually it was quite simple to disable .delete() in querysets, but I had to define my own QuerySet class:

class QuerySet(models.query.QuerySet):
def delete(self):
raise NotImplementedError("delete is not implemented.")

I also disabled bulk_create() in managers for similar reasons. And I thought, maybe you can introduce optional settings in which if it's set, will disable delete() and bulk_create() in managers and querysets? I think this may be useful, since the delete() and bulk_create() methods have problems - they don't call the model's methods and in some cases (such as in my case) related objects from other models don't get deleted (with delete()) and models don't get validated (with bulk_create()).

I also call each model's self.full_clean() method before saving, which may also be a setting in Django. I don't want invalid objects to be saved to the database.

If you think this is a good idea and want me to implement it, I can try to submit a PR.

By the way, I checked and I found out that I can still delete objects from our admin interface, so it probably doesn't use the delete() queryset.

Thanks,
Uri.

Javier Buzzi

unread,
May 20, 2020, 9:04:50 AM5/20/20
to Django developers (Contributions to Django itself)
> I can still delete objects from our admin interface, so it probably doesn't use the delete() queryset.

I think you should look at https://github.com/django/django/blob/master/django/contrib/admin/options.py#L1095-L1103
Individual objects are deleted individually, using the object.delete()

Tom Forbes

unread,
May 20, 2020, 9:06:22 AM5/20/20
to django-d...@googlegroups.com
I don’t think a Django-wide setting to disable Queryset.delete() is appropriate. As you said, it’s easy enough to configure for the specific models that may (or may not!) benefit from this. 

A Django-wide setting like this would also break just about everything that calls “delete()” on a queryset.

Tom

On 20 May 2020, at 13:57, אורי <u...@speedy.net> wrote:


--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/CABD5YeGBinT0uXyCdmw6%3DARAN5URFWk-Sh%3D1wvb8Fbfuj8c_pQ%40mail.gmail.com.

Tim Graham

unread,
May 20, 2020, 9:08:34 AM5/20/20
to Django developers (Contributions to Django itself)
Hi Uri,

I think you've mostly come across documented behaviors rather than "problems". You haven't provided enough details in the bug report to say for sure on that issue.

I don't think the things you've implemented are generally applicable to many Django projects such that they warrant the addition of new settings.

Javier Buzzi

unread,
May 20, 2020, 9:17:38 AM5/20/20
to Django developers (Contributions to Django itself)
More to Tom's point, I'm currently working on an old app that the original intent was to never delete anything, ever. The original programmers did something similar to what you did with the exception that they added a "deleted_ts" field to every model, the  model/queryset delete() would just add now() to the aforementioned field. This all seemed great on the surface, until we realized the app needed tests, they wrote none. Sometimes even in the more severe of cases, you want to do delete(), inside tests or otherwise. As an ongoing effort, we have created a soft_delete() and left delete() alone, created a Admin mixin called SoftDeleteMixin that adds an extra button in the details and a new action to the list view.

What you're suggesting definitely something that should be there, i really suggest you reconsider your approach.
Reply all
Reply to author
Forward
0 new messages