59👍
✅
You can override a Manager's
default QuerySet
by overriding the Manager.get_query_set()
method.
Example:
class MyQuerySet(models.query.QuerySet):
def delete(self):
pass # you can throw an exception
class NoDeleteManager(models.Manager):
def get_query_set(self):
return MyQuerySet(self.model, using=self._db)
class MyModel(models.Model)
field1 = ..
field2 = ..
objects = NoDeleteManager()
Now, MyModel.objects.all().delete()
will do nothing.
For more informations: Modifying initial Manager QuerySets
12👍
mixin approach
https://gist.github.com/dnozay/373571d8a276e6b2af1a
use a similar recipe as @manji posted,
class DeactivateQuerySet(models.query.QuerySet):
'''
QuerySet whose delete() does not delete items, but instead marks the
rows as not active, and updates the timestamps
'''
def delete(self):
self.deactivate()
def deactivate(self):
deleted = now()
self.update(active=False, deleted=deleted)
def active(self):
return self.filter(active=True)
class DeactivateManager(models.Manager):
'''
Manager that returns a DeactivateQuerySet,
to prevent object deletion.
'''
def get_query_set(self):
return DeactivateQuerySet(self.model, using=self._db)
def active(self):
return self.get_query_set().active()
and create a mixin:
class DeactivateMixin(models.Model):
'''
abstract class for models whose rows should not be deleted but
items should be 'deactivated' instead.
note: needs to be the first abstract class for the default objects
manager to be replaced on the subclass.
'''
active = models.BooleanField(default=True, editable=False, db_index=True)
deleted = models.DateTimeField(default=None, editable=False, null=True)
objects = DeactivateManager()
class Meta:
abstract = True
other interesting stuff
- [Django]-Django – set user permissions when user is automatically created using get_or_create
- [Django]-How can I render a ManyToManyField as checkboxes?
- [Django]-Return the current user with Django Rest Framework
Source:stackexchange.com