Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HARD_DELETE in SafeDeleteQueryset bypasses custom delete logic #231

Open
ColemanDunn opened this issue Apr 7, 2023 · 1 comment
Open

Comments

@ColemanDunn
Copy link

When hard deleting a queryset, custom delete logic (aka overriding the delete method in your model with a call to super) is not called, but it is when doing hard delete (force_policy=HARD_DELETE). Any idea why? Is the way around this just to loop over the objects manually. Is it possible to make this not bypass the model's delete method?

For reference, here is the code that shows SafeDeleteQueryset.delete bypassing the model's delete method for when the policy is HARD_DELETE, but normally for the other deletes.

` def delete(self, force_policy: Optional[int] = None) -> Tuple[int, Dict[str, int]]:
"""Overrides bulk delete behaviour.

    .. note::
        The current implementation loses performance on bulk deletes in order
        to safely delete objects according to the deletion policies set.

    .. seealso::
        :py:func:`safedelete.models.SafeDeleteModel.delete`
    """
    assert self.query.can_filter(), "Cannot use 'limit' or 'offset' with delete."

    if force_policy == NO_DELETE:
        return (0, {})
    elif force_policy == HARD_DELETE:
        return self.hard_delete_policy_action()
    else:
        deleted_counter: Counter = Counter()
        # TODO: Replace this by bulk update if we can
        for obj in self.all():
            _, delete_response = obj.delete(force_policy=force_policy)
            deleted_counter.update(delete_response)
        self._result_cache = None
        return sum(deleted_counter.values()), dict(deleted_counter)
delete.alters_data = True  # type: ignore

def hard_delete_policy_action(self) -> Tuple[int, Dict[str, int]]:
    # Normally hard-delete the objects.
    self.query._filter_visibility()
    return super().delete()

`

@Gagaro
Copy link
Member

Gagaro commented Apr 11, 2023

Yes that's the default Django behavior.

We iterate over the objects otherwise to be able to handle all other policies. That's clearly not the most optimized way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants