django - django 检查约束布尔表达式 [postgresql]
问题描述
所以我有一个这样的模型
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)
基本上我想对该模型强制执行检查约束,以便当模型将is_default
字段设置为 True 时,
- 名称必须始终是
@everyone
- 颜色必须始终是
#969696
- 位置必须始终为
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)
推荐阅读
- sql-server - ssis ole db 目标 ALL_SPARSE_COLUMNS 缺少所有 SPARSE 字段
- android - 无法将 android 客户端连接到 Laravel Web 套接字(Web 套接字的代码之外)
- java - 如何在标题栏的中心设置应用程序的标题?
- prometheus - Prometheus-am-executor 中的 executor.yml 文件问题
- flutter - 将颤动下拉菜单更改为 textalign left
- ipv6 - 在 eBPF 中将 IPv4 转换为 IPv6 时,“bpf_l4_csum_replace”的校验和计算问题
- mongodb - Mongo 4.2 错误输出阶段需要一个字符串参数,但找到了对象
- javascript - 为字符串添加右填充,使其以一致的行/列结构显示
- paypal - Paypal 沙箱 INVALID_RESOURCE_ID RESOURCE_NOT_FOUND
- flutter - 如何在 Flutter 的 Choice Chip 中不选择索引的情况下打印值