我有一个汽车零件数据库,包括品牌和无品牌商品。如果品牌名称不可用,则full_name
只是Part.name
,否则为Brand.name + Part.name
。
如何定义unique_together
约束以确保full_name
在数据库级别的唯一性?如果缺少品牌名称,则当前约束允许多个具有相同名称的部分(即brand_id
ForeignKey
为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'),)
使用:Django 1.6 + PostgreSQL 9.3
P.S。这里有一个很好的建议,用SQL实现这一目标。我正在寻找使用Django ORM的解决方案。 https://stackoverflow.com/a/8289253/781695
答案 0 :(得分:5)
我无法告诉django添加该索引,我担心,unique_together
只能处理简单的索引。但是,您可以使用clean
方法在模型层验证,在保存模型实例之前应该调用该方法(ModelForm实例为您调用):
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')
理想情况下,您应该使用迁移中的RunSQL
操作手动将索引添加到Postgres数据库。