Reputation: 131
Suppose that I have django models such A ->B ->C ->D in the default database.
C is a foreign key in D,similarly B in C and C in A.
On the deletion of the object A,the default behaviour of Django is that all the objects related to A directly or indirectly will get deleted automatically(On delete cascade).Thus, B,C,D would get automatically deleted.
I want to implement deletion in a way such that on deletion of an object of A it would get moved to another database named 'del'.Also along with it all other related objects of B,C,D will also get moved.
Is there an easy way of implementing this in one go?
Upvotes: 6
Views: 6709
Reputation: 431
maybe you could try https://github.com/drneox/django-paranoid
allows to perform soft delete and also revert it.
Use:
from django_paranoid.admin import ParanoidAdmin
class MyModelAdmin(ParanoidAdmin):
pass
soft delete:
m = MyModel.objects.last()
m.delete()
m = MyModel.objects.last()
>>> m
>>>
get deleted object:
m = MyModel.objects_with_deleted.last()
>>> m
<MyModel: name>
>>> m.deleted_at
datetime.datetime(2019, 8, 10, 6, 16, 44, 633727, tzinfo=<UTC>)
restore object:
m.restore()
hard delete:
m = MyModel.objects.last()
m.delete(True)
Upvotes: 0
Reputation: 9342
There is a library that matches django's default delete behavior on soft deletes. (ie uses the Cascade, do nothing, etc options from the model specification).
https://github.com/upgrad/django-deletes
PS: The library is still in beta mode, but active development.
Upvotes: 0
Reputation: 131
I have implemented this thing using a deleted flag on each model of my database instead of moving things to separate database as follows:
deleted = models.BooleanField(default=False)
And defined a soft_del function for each model as follows:
def soft_del(self):
self.deleted = True
self.save()
So the deleted models would exist in the same database with deleted flag set to True.
Also to produce an ON DELETE CASCADE effect I have added such soft_del functions to each model and given a related_name to each foreign key in the model as follows:
class B(models.Model)
a = models.ForeignKey(A,related_name='related_Bs'))
and then call the soft_del of child when inside the soft_del of parent as follows:
def soft_del_A(self):
self.deleted = True
for b in A.related_Bs.all():
b.soft_del_B()
self.save()
Upvotes: 7
Reputation: 10135
Just override delete
method of model A
and check relation before delete. If it isn't empty - move object to another table/DB.
Upvotes: 2