Skip to content

Custom UniqueConstraint do not works with OneToOneField #241

@LECARROU

Description

@LECARROU

I use many models with OneToOneField with default unique=True.

I would like the user to be able to create a record in table Exam even if one or more records are marked as soft (logically) deleted and linked to the same record in table Followup.
But when I have a model with OneToOneField, if I deleted a record 1 in table Exam linked to a record 1 in table Followup and I try to recreate a record 2 in table Exam linked to the same record 1 from table Followup, I get an IntegrityError because the uniqueness is not respected.

I read about the possibility of "revive" a deleted object but that's not what I want. I want to have multiple deleted records but only one undeleted one that respects the integrity of the constraints.
I read the section on field uniqueness in the documentation where a unique constraint can be set to exclude deleted records.
I try to implement this UniqueConstraint but it doesn't works.

I try to customize a ModelManager to set _safedelete_visibility = DELETED_VISIBLE_BY_PK but doesn't seems to works.
In my Postgresql database, a soft deleted object is not accessible with Exam.objects.filter(uuid='my-uuid') wherease it is for non soft deleted objects.

class Followup(SafeDeleteModel):
    _safedelete_policy = SOFT_DELETE_CASCADE
    uuid = models.UUIDField(default=uuid.uuid4, max_length=36, null=False, unique=True, primary_key=True)
    date = models.DateField("Date", null=True, blank=True)
    
class Exam(SafeDeleteModel):
    _safedelete_policy = SOFT_DELETE_CASCADE
    uuid = models.UUIDField(default=uuid.uuid4, max_length=36, null=False, unique=True, primary_key=True)
    followup = models.OneToOneField(Followup, null=True, blank=True, on_delete=models.CASCADE, related_name='exam', default=None)
    class Meta:
        constraints = [
            UniqueConstraint(
                fields=['followup'],
                condition=Q(deleted__isnull=True),
                name='unique_active_one_to_one_field'
            ),
        ]
    

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