Skip to content

SET_NULL on deleting erases the relation #244

Description

@FranciscodeMaussion

Problem Statement

We were having trouble un-deleting objects that had a relation to a model with on_delete=models.SET_NULL since the relation is lost and couldn't be automatically restored when undeleting.

For example:

class ModelB(SafeDeleteModel):
    pass

class ModelA(SafeDeleteModel):
    model_b = models.OneToOneField(
        ModelB,
        on_delete=models.SET_NULL,
        null=True,
        blank=True,
    )

Solution/or maybe a Workaround

I created a custom policy SET_NULL_ONLY_ON_HARD_DELETE

def SET_NULL_ONLY_ON_HARD_DELETE(collector, field, sub_objs, using):
    """
    This method is used to set the field to null only when related object is hard deleted.

    As for soft_delete_cascading deletion this works as SET_NULL/SET/SET_DEFAULT.
    See https://github.com/makinacorpus/django-safedelete/blob/master/safedelete/models.py#L247.

    Default collector(used on hard delete) does not have the edges attribute,
    so we can use it to differentiate between hard and soft delete.
    Default collector: https://github.com/django/django/blob/stable/5.1.x/django/db/models/deletion.py#L94
    Admin/Soft delete collector: https://github.com/django/django/blob/stable/5.1.x/django/contrib/admin/utils.py#L186
    """
    if hasattr(collector, "edges"):
        return models.DO_NOTHING(collector, field, sub_objs, using)
    return models.SET_NULL(collector, field, sub_objs, using)


SET_NULL_ONLY_ON_HARD_DELETE.lazy_sub_objs = True

I don't know if should be contributed to the main package. Just let me know!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions