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

Unique constraints are not validated by clean #203

Open
tartieret opened this issue Apr 7, 2022 · 2 comments
Open

Unique constraints are not validated by clean #203

tartieret opened this issue Apr 7, 2022 · 2 comments

Comments

@tartieret
Copy link

Context

As mentioned in the documentation (https://django-safedelete.readthedocs.io/en/latest/models.html#fields-uniqueness), if we need to define a field uniqueness for non-deleted objects, we have to define a custom constraint such as:

class Product(SafeDeleteModel):

    name = models.CharField(
        max_length=100, verbose_name=_("name"), help_text=_("Name of the product")
    )

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=["name"],
                condition=Q(deleted=None),
                name="product_unique_if_not_deleted",
            )
        ]

However, since we have to add a "condition" on the constraint, Product.has_unique_fields returns False and uniqueness validation is not performed when calling the model .clean method. This means that any model implementing this strategy has to implement custom validation for it

Root cause

The django model has_unique_fields and _perform_unique_checks are overwritten in models.SafeDeleteModel, but they exclude unique constraints with conditions, as shown below:

image

Solution

A potential solution is to modify the overwritten has_unique_fields and _perform_unique_checks. I am happy to submit a PR for these changes, but what do you think of this change @Gagaro @AndreasBackx @palkeo ?

@Gagaro
Copy link
Member

Gagaro commented Apr 8, 2022

We should (hopefully) have that fixed with Django 4.1 (cf django/django#14625).

With this change, we'll have to refactor a bit what we are doing in safedelete to make it all work.

@tartieret
Copy link
Author

Looks like you are on top of it ! 😄
It makes sense to solve this in Django itself. Please let me know if you need help with the changes to django-safedelete, we use it at work and could allocate some time to it if needed

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