jdickson
jdickson

Reputation: 724

Django unique=True except for blank values

I have this model:

class Part(models.Model):
    serial_number = models.CharField(max_length=15, null=True, blank=True, validators=[validate_serial], unique=True)
    ....

serial_number can be blank and null because all parts don't necessarily have a serial number. However, after storing one part without a serial number, blank is no longer unique and I get this error:

Part with this Serial number already exists.

Is there a workaround for this? I already looked at this question, but I don't have a modelform. I either use the admin or do it directly in the code.

Upvotes: 13

Views: 5668

Answers (3)

jnns
jnns

Reputation: 5634

Django supports creating unique constraints that have conditions. A custom constraint can be created that enforces uniqueness for a given field only under the condition that a field's value is not blank.

from django.db.models import Q

serialnumber_is_not_blank = ~Q(serial_number="")

class Meta:
   constraints = [
        models.UniqueConstraint(
            fields=["serial_number"],
            condition=serialnumber_is_not_blank,
            name="unique_serial_number",
        )
    ]

Upvotes: 5

SaeX
SaeX

Reputation: 18711

I came across the same issue and fixed it by specifying None for the field when saving.

Specifying default=None could be helpful as well.

Upvotes: 4

guidoism
guidoism

Reputation: 8158

I'm pretty sure that having null values aren't taken into account in uniqueness constraints. The way to get around this is to not use null, but instead use an empty string. So, remove null=True.

Upvotes: -2

Related Questions