Unique_together for multiple NULL columns

I have a database of car parts that includes branded and unpainted items. If the brand name is not available, full_name

just Part.name

, otherwise it is Brand.name + Part.name

.

How do I define a constraint unique_together

to enforce uniqueness full_name

at the database level? The current limitation allows multiple parts with the same name if the brand name is missing (i.e. brand_id

ForeignKey

there is NULL

)

class Brand(models.Model):
    name = models.CharField(max_length=100)

class Part(models.Model);
    name = models.CharField(max_length=100)
    brand = models.ForeignKey(Brand, null=True, blank=True)

    def get_full_name(self):
        if self.brand_id:
            full_name = '%s %s'.format(self.brand.name, self.name)
        else:
            full_name = self.name
        return full_name

    class Meta:
        unique_together = (('name', 'brand'),) 

      

Usage: Django 1.6 + PostgreSQL 9.3

PS There is a great suggestion for doing this with SQL. I am looking for a solution using Django ORM. StackoverflowStackoverflow

+3


source to share


1 answer


There is no way to tell django to add this index, which I fear unique_together

only handles simple indexes. However, you can check at the model level with a method clean

you must call before saving the model instance (ModelForm instances call it for you):

from django.core.validators import ValidationError

class Part(models.Model):

    def clean(self):
        duplicates = Part.objects.exclude(pk=self.pk).filter(name=self.name)
        if self.brand:
            duplicates = duplicates.filter(brand=self.brand)
        if duplicates.count():
            raise ValidationError(u'Duplicate part/brand')

      



Ideally, you should manually add the index to your Postgres database using RunSQL

in your migrations.

+4


source







All Articles