Py学习  »  Django

按字段值约束Django模型

ZG101 • 5 年前 • 1503 次点击  

考虑以下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 ,但仅当 水平 m .

我知道我可以手动检查保存,但我希望数据库自动检查并提出 IntegrityError 在适当的时候。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/38078
 
1503 次点击  
文章 [ 1 ]  |  最新文章 5 年前
Selcuk
Reply   •   1 楼
Selcuk    6 年前

我不认为你能用你目前的模式做到这一点,但如果这是唯一的两个选择 level 字段,考虑将其更改为可以为空的 BooleanField 例如,

is_main = models.BooleanField(null=True) 

并将其设置为 None 对于二级帐户。然后一个 unique_together 将起作用,因为就SQL而言,每个空值都是唯一的(请参见 this answer )

因为有更多的选择 水平 字段,正如您稍后澄清的,您可以添加第三个字段,并可能重写 .save() 方法将其自动设置为 没有 如果 水平 不是 "m" 为了额外的便利。

编辑: 如果您不关心可移植性, @Trent 建议PostgreSQL支持部分唯一索引,例如:

create unique index u_i on accounts(user_id, level_id) WHERE level_id = 'm';

这是一个 SQL Fiddle .