考虑以下Django模型:
class Account(models.Model):
ACCOUNT_CHOICES = [
('m', 'Main',),
('s','Secondary'),
('o', 'Other')
]
user = models.ForeignKey(User)
level = models.CharField(max_length=1, choices=ACCOUNT_CHOICES)
如何在每个用户最多执行一个“主要”帐户的数据库约束,同时仍允许用户使用任何数量的“次要”或“其他”帐户?从某种意义上说,我希望unique_together
代表user
和level
,但仅当level
的值为m
时。
我知道我可以手动检查保存,但是我希望数据库能够自动检查并在适当的时候引发IntegrityError
。
答案 0 :(得分:2)
我认为您无法使用当前模型进行此操作,但是例如,如果这些是level
字段的唯一两个选择,请考虑将其更改为可为空的BooleanField
,例如>
is_main = models.BooleanField(null=True)
,然后将其设置为None
(用于辅助帐户)。然后unique_together
将起作用,因为就SQL而言,每个空值都是唯一的(请参见this answer)。
由于后面将要说明的level
字段还有更多选择,因此您可以添加第三个字段,并可能覆盖.save()
方法,以使其自动设置为None
,如果{ {1}}并非level
,这是为了提供更多便利。
编辑::如果您不担心可移植性,@Trent建议PostgreSQL支持部分唯一索引,例如:
"m"
这里是SQL Fiddle。
编辑2:实际上,看来终于可以从Django 2.2开始在Django ORM中创建部分索引了。有关详细信息,请参见this question。