Python Django:更复杂的唯一性约束?

Python Django:更复杂的唯一性约束?,python,sql,django,Python,Sql,Django,在我的模型中: class MyModel(models.Model): active = models.BooleanField() path = models.CharField(max_length = 512) 我想限制“path”属性在active为True的实例中是唯一的 似乎覆盖save()可能不起作用,因为如果两个保存同时完成,则两个保存都可能通过测试并继续保存。是否有一些技巧或自定义SQL(我使用的是MySQL)可以用来在数据库级别使用这样的条件唯一性约束?您可能需要

在我的模型中:

class MyModel(models.Model):
  active = models.BooleanField()
  path = models.CharField(max_length = 512)
我想限制“path”属性在active为True的实例中是唯一的


似乎覆盖save()可能不起作用,因为如果两个保存同时完成,则两个保存都可能通过测试并继续保存。是否有一些技巧或自定义SQL(我使用的是MySQL)可以用来在数据库级别使用这样的条件唯一性约束?

您可能需要的是模型验证。这是在1.2中介绍的,并且有很好的文档记录

虽然您可以编写一些复杂的SQL来实现这一点,但只要数据库行都是通过Django ORM创建的,那么模型验证就是更易于维护的解决方案


旁白:我感兴趣的是如何在数据库级别完成这项工作,而不是使用某种级别的预提交触发器。一个值依赖于另一个值的唯一性是真实的,这是我没有看到的模式。在active+path上有一个2字段的唯一约束将允许给定路径值有1个false、1个true和任意数量的NULL活动行(假设active可以为NULL,例如NullBooleanField将提供)。

Hmm,验证内容似乎相当于覆盖save()(尽管使用表单时更简洁)。但是,将字段置零而不是使用True/False是一个有趣的想法。我想我可以有一个“非活动”字段,该字段为真或无,然后一起唯一(路径,非活动),是吗?你可以。我不确定django是否正确地应用了unique_-together约束-它可能正确,但我想检查一下。我反对这样做的唯一原因是,我对空值以及它们在语义上如何表示与False不同的东西有点清教徒的味道。哦,django管理员似乎讨厌空值,并用空字符串替换它们。让我明确一点:我喜欢空值,只是讨厌它们不被用作空值。“一个值依赖于另一个值的唯一性[sic]是真的,这是我没有见过的模式”-我见过,最好将其描述为反模式。设想一行需要删除,但设计者对数据丢失心存疑虑。因此,不是“物理”删除该行,而是通过将其
active
属性设置为FALSE来“逻辑”删除该行。然后需要能够重用“已删除”实体的键值,因此问题……这是一种模式,因为针对表编写的所有查询都必须记住过滤
active=TRUE
,因为没有人真正对“已删除”行感兴趣,当然,当编码人员忘记时,这会导致错误。使用
VIEW
s仅公开“活动”行可以改善这一点,但更好的解决方案是在“物理”删除行时使用触发器将行复制到“审核”表。