繁体   English   中英

django 检查约束 boolean 表达式 [postgresql]

[英]django check-contraint boolean expression [postgresql]

所以我有一个像这样的 model

class Role(BaseModel):

    class Meta:
        verbose_name = 'role'
        verbose_name_plural = 'roles'
        ordering = ['position', 'cluster']
        required_db_features = {
            'supports_deferrable_unique_constraints',
        }
        constraints = [
            models.UniqueConstraint(
                fields=['position', 'cluster'],
                name='deferrable_unique_role_position',
                deferrable=models.Deferrable.DEFERRED
            ),
            models.CheckConstraint(
                name='default_role_check',
                check=models.Q(
                    is_default=True,
                    position=1,
                    color='#969696',
                    name='@everyone'
                )
            )
        ]

    permission_flags = [
        'READ_DATA', 'WRITE_DATA', 'MANAGE_RECORDS', 'MANAGE_ROLES',
        'MANAGE_CLUSTER', 'MANAGE_DATASHEETS', 'MANAGE_FIELDS', 'MANAGE_CONSTRAINTS',
        'KICK_MEMBERS', 'MANAGE_MEMBERS',
    ]

    default_perm_flags = ['READ_DATA', 'WRITE_DATA', 'MANAGE_RECORDS']

    def __str__(self):
        return self.name

    objects = managers.RolesManager()
    positions = managers.PositionalManager()
    permissions = BitField(flags=permission_flags, default=default_perm_flags, db_index=True)
    position = models.PositiveSmallIntegerField(null=True, blank=True, db_index=True, editable=True)
    name = models.CharField(max_length=100, validators=[MinLengthValidator(2)], db_index=True, default='new role')
    color = ColorField(db_index=True, default='#969696')
    is_default = models.BooleanField(default=False, db_index=True)
    cluster = models.ForeignKey('api_backend.Cluster', on_delete=models.CASCADE, editable=False)

基本上我想对这个 model 实施检查约束,这样当 model 的is_default字段设置为 True 时,

  • 名称必须始终为@everyone
  • 颜色必须始终为#969696
  • position 必须始终为1

我尝试实现相同的功能,但是我当前的实现不起作用。 在使用序列化程序时,我可以编辑默认角色的名称,并且不会引发异常。

我在后端使用 postgresql。

有人可以帮帮我吗? 提前致谢!

添加is_default=False案例让您更接近您的条件。

我用 Django==3.1.4 进行了测试,OR 方法导致了这个约束:

"default_role_check" CHECK (color::text = '#969696'::text AND is_default AND name::text = '@everyone'::text AND "position" = 1 OR NOT is_default)

约束示例:

class Role(BaseModel):

    class Meta:
        verbose_name = 'role'
        verbose_name_plural = 'roles'
        ordering = ['position', 'cluster']
        required_db_features = {
            'supports_deferrable_unique_constraints',
        }
       constraints = [
            models.UniqueConstraint(
                fields=['position', 'cluster'],
                name='deferrable_unique_role_position',
                deferrable=models.Deferrable.DEFERRED
            ),
            models.CheckConstraint(
                name='default_role_check',
                check=(models.Q(
                    is_default=True,
                    position=1,
                    color='#969696',
                    name='@everyone'
                ) |
                    models.Q(
                    is_default=False,
                )
                )
            )
        ]
    permission_flags = [
        'READ_DATA', 'WRITE_DATA', 'MANAGE_RECORDS', 'MANAGE_ROLES',
        'MANAGE_CLUSTER', 'MANAGE_DATASHEETS', 'MANAGE_FIELDS', 'MANAGE_CONSTRAINTS',
        'KICK_MEMBERS', 'MANAGE_MEMBERS',
    ]

    default_perm_flags = ['READ_DATA', 'WRITE_DATA', 'MANAGE_RECORDS']

    def __str__(self):
        return self.name

    objects = managers.RolesManager()
    positions = managers.PositionalManager()
    permissions = BitField(flags=permission_flags, default=default_perm_flags, db_index=True)
    position = models.PositiveSmallIntegerField(null=True, blank=True, db_index=True, editable=True)
    name = models.CharField(max_length=100, validators=[MinLengthValidator(2)], db_index=True, default='new role')
    color = ColorField(db_index=True, default='#969696')
    is_default = models.BooleanField(default=False, db_index=True)
    cluster = models.ForeignKey('api_backend.Cluster', on_delete=models.CASCADE, editable=False)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM