首页 > 解决方案 > Django 2.2 - 如何表达两个字段之间的约束

问题描述

我有几个看起来像这样的模型:

class AlarmStatus(Enum):
    UNDEFINED = "Undefined"
    PENDING = "Pending"
    CUSTOMER_PENDING = "Customer Pending"

    @classmethod
    def choices(cls):
        return tuple((i.name, i.value) for i in cls)


class Alarm(models.Model):
    managed = models.BooleanField(default=False, blank=False, verbose_name="Managed ?")
    status = models.CharField(
        max_length=20, default=AlarmStatus.UNDEFINED.name, choices=AlarmStatus.choices()
    )

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=Q(managed=False) & Q(status=AlarmStatus.UNDEFINED.name),
                name="if_managed_is_False_status_must_be_UNDEFINED")
               ]

我想在数据库级别强制执行以下不变量:

如果警报managed字段为 False,则其status字段必须为 "UNDEFINED"

即我想声明以下状态/组合为非法:

managed== 错误和status==(待定 | CUSTOMER_PENDING)

我该如何执行?

我尝试了上述约束,但它显然是错误的,因为它强制每个行managed字段必须为 False 并且每行都status必须是 UNDEFINED。

谢谢

标签: djangodatabaseconstraints

解决方案


蕴涵[wiki](即A → B)可以表示为¬A∨B,因此您可以将其表示为:

models.CheckConstraint(
    check=Q(managed=True) | Q(status=AlarmStatus.UNDEFINED.name),
    name="if_managed_is_False_status_must_be_UNDEFINED"
)

因此,这意味着如果managed是,则满足检查True(从那时起我们不关心status,或者状态应该是UNDEFINED


推荐阅读