7

So every model comes with some commonly used functions such as save and delete.

Delete is often overridden to set a boolean field such as is_active to false, this way data is not lost. But sometimes a model exists that has information that, once created, should always exist and never even be "inactive". I was wondering what the best practice for handling this model's delete method would be?

ideas

make it simply useless:

def delete(self):
    return False

but that just seems odd. Is there maybe a Meta option to disable deleting? is there any "nice" way to do this?

Community
  • 1
  • 1
Ryan Saxe
  • 17,123
  • 23
  • 80
  • 128

2 Answers2

2

Well it depends, you cannot truly restrict deletion, because somebody can always call delete() on queryset or just plain DELETE sql command. If you want to disable delete button in django admin though, you should look here.

Community
  • 1
  • 1
Dmitry Shevchenko
  • 31,814
  • 10
  • 56
  • 62
  • 1
    Django admin is irrelevant to this. I know I cannot get rid of the SQL `DELETE`, but I want to remove it from the model and queryset in a nice way. The only people who should be able to delete these instances are those with access to the actual database, but those with access to the django querying should not be able to – Ryan Saxe Dec 20 '13 at 19:52
  • 1
    Then yeah, override delete on model and create a custom query set with custom manager to disable that. You would also want to look into related querysets that you can get by traversing relations. – Dmitry Shevchenko Dec 20 '13 at 19:54
  • 2
    And also if people have access to django app, don't they have access to database? I would restrict deletions on DB level to only admins, or something. – Dmitry Shevchenko Dec 20 '13 at 19:55
  • They have access to an API made with Django, so I control what they can call, so I want to make them not able to delete. Therefore in this specific model I would remove the delete capabilities and the raw SQL abilities. – Ryan Saxe Dec 20 '13 at 21:42
0

delete() on queryset can be restricted with this:

class NoDeleteQuerySet(models.QuerySet):
    def delete(self, *args, **kwargs):
        pass

class MyModel(models.Model):
    objects = NoDeleteQuerySet.as_manager()
    ...

Django docs - link

Sergey Geron
  • 9,098
  • 2
  • 22
  • 29