Model¶
Built-in model¶
-
class
safedelete.models.
SafeDeleteModel
(*args, **kwargs)[source]¶ Abstract safedelete-ready model.
Note
To create your safedelete-ready models, you have to make them inherit from this model.
Attribute deleted: DateTimeField set to the moment the object was deleted. Is set to
None
if the object has not been deleted.Attribute deleted_by_cascade: BooleanField set True whenever the object is deleted due cascade operation called by delete method of any parent Model. Default value is False. Later if its parent model calls for cascading undelete, it will restore only child classes that were also deleted by a cascading operation (deleted_by_cascade equals to True), i.e. all objects that were deleted before their parent deletion, should keep deleted if the same parent object is restored by undelete method.
If this behavior isn’t desired, class that inherits from SafeDeleteModel can override this attribute by setting it as None: overriding model class won’t have its
deleted_by_cascade
field and won’t be restored by cascading undelete even if it was deleted by a cascade operation.>>> class MyModel(SafeDeleteModel): ... deleted_by_cascade = None ... my_field = models.TextField()
Attribute _safedelete_policy: define what happens when you delete an object. It can be one of
HARD_DELETE
,SOFT_DELETE
,SOFT_DELETE_CASCADE
,NO_DELETE
andHARD_DELETE_NOCASCADE
. Defaults toSOFT_DELETE
.>>> class MyModel(SafeDeleteModel): ... _safedelete_policy = SOFT_DELETE ... my_field = models.TextField() ... >>> # Now you have your model (with its ``deleted`` field, and custom manager and delete method)
Attribute objects: The
safedelete.managers.SafeDeleteManager
returns the non-deleted models.Attribute all_objects: The
safedelete.managers.SafeDeleteAllManager
returns all the models (non-deleted and soft-deleted).Attribute deleted_objects: The
safedelete.managers.SafeDeleteDeletedManager
returns the soft-deleted models.-
save
(keep_deleted=False, **kwargs)[source]¶ Save an object, un-deleting it if it was deleted.
- Args:
- keep_deleted: Do not undelete the model if soft-deleted. (default: {False})
kwargs: Passed onto
save()
.
Note
Undeletes soft-deleted models by default.
-
-
class
safedelete.models.
SafeDeleteMixin
(*args, **kwargs)[source]¶ SafeDeleteModel
was previously namedSafeDeleteMixin
.Deprecated since version 0.4.0: Use
SafeDeleteModel
instead.
Policies¶
You can change the policy of your model by setting its _safedelete_policy
attribute.
The different policies are:
-
safedelete.models.
HARD_DELETE
¶ - This policy will:
Hard delete objects from the database if you call the
delete()
method.There is no difference with « normal » models, but you can still manually mask them from the database, for example by using
obj.delete(force_policy=SOFT_DELETE)
.
-
safedelete.models.
SOFT_DELETE
¶ This policy will:
This will make the objects be automatically masked (and not deleted), when you call the delete() method. They will NOT be masked in cascade.
-
safedelete.models.
SOFT_DELETE_CASCADE
¶ This policy will:
This will make the objects be automatically masked (and not deleted) and all related objects, when you call the delete() method. They will be masked in cascade.
-
safedelete.models.
HARD_DELETE_NOCASCADE
¶ - This policy will:
- Delete the object from database if no objects depends on it (e.g. no objects would have been deleted in cascade).
- Mask the object if it would have deleted other objects with it.
-
safedelete.models.
NO_DELETE
¶ - This policy will:
- Keep the objects from being masked or deleted from your database. The only way of removing objects will be by using raw SQL.
Policies Delete Logic Customization¶
Each of the policies has an overwritable function in case you need to customize a particular policy delete logic. The function per policy are as follows:
Policy | Overwritable Function |
---|---|
SOFT_DELETE | soft_delete_policy_action |
HARD_DELETE | hard_delete_policy_action |
HARD_DELETE_NOCASCADE | hard_delete_cascade_policy_action |
SOFT_DELETE_CASCADE | soft_delete_cascade_policy_action |
Example:
To add custom logic before or after the execution of the original delete logic of a model with the policy SOFT_DELETE you can overwrite the soft_delete_policy_action
function as such:
def soft_delete_policy_action(self, **kwargs):
# Insert here custom pre delete logic
super().soft_delete_policy_action(**kwargs)
# Insert here custom post delete logic
Fields uniqueness¶
Because unique constraints are set at the database level, set unique=True on a field will also check uniqueness against soft deleted objects. This can lead to confusion as the soft deleted objects are not visible by the user. This can be solved by setting a partial unique constraint that will only check uniqueness on non-deleted objects:
class Post(SafeDeleteModel):
name = models.CharField(max_length=100)
class Meta:
constraints = [
UniqueConstraint(
fields=['name'],
condition=Q(deleted__isnull=True),
name='unique_active_name'
),
]