DeleteView marking inactive instead deleting?
Is there some elegant solution to using Django's DeleteView but instead actually deleting the objects, marking them inactive? I like the simplicity of the DeleteView but would want to keep the data at the backend, instead of removing it.
3 answers
-
answered 2018-10-11 20:07
Kristiyan Gospodinov
The DeleteView inherits DeletionMixin so you can just predefine the delete method. DeletionMixin
-
answered 2018-10-12 03:59
a_k_v
Override delete method in DeleteView as follows
class Example(DeleteView): def delete(self, request, *args, **kwargs): """ Calls the delete() method on the fetched object and then redirects to the success URL. """ self.object = self.get_object() self.object.is_deleted = True # Declare a boolean field is_deleted in your model. Default value is Flase. return HttpResponseRedirect(self.get_success_url())
-
answered 2018-10-12 04:59
Dhirendra
Elegant solution would be overriding
Model
&Manager
to update a field ondelete
. This is an implementation as Abstract Model, so that it can be extended by any other Model. You can modify it as per your need, if you already have delete fields in your model.Soft Deletion Abstract Model
class SoftDeletionModel(models.Model): deleted_at = models.DateTimeField(blank=True, null=True) objects = SoftDeletionManager() all_objects = SoftDeletionManager(alive_only=False) class Meta: abstract = True def delete(self): self.deleted_at = timezone.now() self.save() def hard_delete(self): super(SoftDeletionModel, self).delete()
Object Manager
class SoftDeletionManager(models.Manager): def __init__(self, *args, **kwargs): self.alive_only = kwargs.pop('alive_only', True) super(SoftDeletionManager, self).__init__(*args, **kwargs) def get_queryset(self): if self.alive_only: return SoftDeletionQuerySet(self.model).filter(deleted_at=None) return SoftDeletionQuerySet(self.model) def hard_delete(self): return self.get_queryset().hard_delete()
QuerySet
class SoftDeletionQuerySet(QuerySet): def delete(self): return super(SoftDeletionQuerySet, self).update(deleted_at=timezone.now()) def hard_delete(self): return super(SoftDeletionQuerySet, self).delete() def alive(self): return self.filter(deleted_at=None) def dead(self): return self.exclude(deleted_at=None)
For explanation, see Soft Deletion in Django