【问题标题】:How do I add a database constraint in a Many-to-Many Relation如何在多对多关系中添加数据库约束
【发布时间】:2021-03-05 01:51:37
【问题描述】:

我有以下型号:

class School(models.Model):
    principal = models.OneToOneField(User, on_delete=models.CASCADE)

User 模型是 Django 的标准验证模型。我只想让 school.principal 成为属于 Principals 组的 User 模型的实例。 (按组,我也是指 Django 的股票认证Group 模型)。

我基本上被卡在检查的实施方式上:

class School(models.Model):
    principal = models.OneToOneField(User, on_delete=models.CASCADE)

    class Meta:
        constraints = [
            models.CheckConstraint(
                check=<allow_only_User_instances_that_belongs_to_the_Principals_group>,
                name='principal_is_actually_a_principal',
            ),
        ]

如果需要特定于数据库/Django 版本的实现,我正在使用以下堆栈:

  • Python 3.8
  • Django 3.1
  • PostgreSQL 12.1

我知道我可以在应用程序级别添加检查,但是拥有数据库约束让我确信我的数据始终处于有效状态。任何帮助或推动正确方向都将不胜感激。

谢谢!

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    简单的回答:这是不可能的。

    如果我理解得很好,您希望使用 Principal 表扩展 User 表,但您只希望属于“principal”组的用户能够拥有这样的扩展。 我想这个想法是保持 User 和 Group 表不变,并为“主要”用户提供额外的数据。

    外键的性质不允许您这样做。他们一次操作一个列,没有“加入”机制,也没有过滤器,这意味着你不能要求“GroupUser”->“Group”->只有“principal”名称。

    如果您想利用外键,有时您必须创建一个仅包含主体组用户的表。您必须使用触发器,这反过来会破坏使用外键的目的:您可以直接删除或创建 Principal 行,而无需依赖“PrincipalUser”表。

    我不知道你的框架内的触发器,但它会是要走的路。

    【讨论】:

    • 谢谢。看来我必须解决在应用程序级别应用约束。
    猜你喜欢
    • 2019-06-20
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 2012-10-13
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多