这是我的模型:
class GroupedModels(models.Model):
other_model_one = models.ForeignKey('app.other_model')
other_model_two = models.ForeignKey('app.other_model')
本质上,我想要的是other_model
在这个表中是唯一的。这意味着如果有一个记录,其中other_model_one
id是123
,我不应该允许用other_model_two
id作为123
创建另一个记录。我可以重写clean
我想,但我想知道django是否有内置的功能。在
我使用的是PSQL版本2.2.5。在
编辑:这不是一个不齐聚的情况。如果我添加一个带有other_model_one_id=1
和其他other_model_two_id=2
的记录,我将不能添加另一个带有other_model_one_id=2
和其他{
已经有一个来自dani herrera的伟大的answer,但是我想进一步详细说明它。在
如第二个选项所述,OP所需的解决方案是更改设计并成对实现两个唯一约束。与篮球比赛的类比很实际地说明了这个问题。在
我用足球(或足球)比赛作为例子,而不是篮球比赛。足球比赛(我称之为}限制为两个在这种特殊情况下,该原理适用于无限个数。在
Event
)由两个团队进行(在我的模型中,一个团队是Competitor
)。这是一个多对多关系(m:n
),其中{以下是我们的模型的外观:
事件可以是:
现在我们要从问题上解决问题。Django自动在具有多对多关系的模型之间创建一个中间表,但是我们可以使用自定义模型并添加更多字段。我把这个模型称为
^{pr2}$Participant
:ManyToManyField
有一个选项through
,它允许我们指定中间模型。让我们在模型Event
中更改它:独特的限制条件现在会自动将每个赛事的参赛者数量限制在两个(因为只有两个角色:主场和观众)。在
在一个特定的项目(足球比赛)中,只能有一个主队和一个客队。俱乐部(
Competitor
)可以作为主队或客队出现。在我们现在如何管理所有这些事情?像这样:
我们已经将
Participant
作为内联添加到EventAdmin
中。当我们创建新的Event
时,我们可以选择主团队和访问者团队。因此,{cd2>每一个事件可以添加更多的条目。在这可以针对不同的用例进行重构。假设我们的项目是游泳比赛,而不是主场和游客,我们有1至8泳道。我们只需重构
Participant
:通过此修改,我们可以进行以下活动:
标题:国际泳联2019,50米仰泳男子决赛
参加人员:
//以此类推,从第5道到第8道(来源:Wikipedia
一个游泳者在炎热的天气里只能出现一次,而一条泳道在炎热的天气里只能被占用一次。在
我把代码放到GitHub:https://github.com/cezar77/competition。在
再说一遍,所有的学分都归丹尼·赫雷拉所有。我希望这个答案能为读者提供一些附加值。在
我在这里解释几个选项,也许其中一个或一个组合对你有用。在
重写
save
您的约束是业务规则,您可以重写
save
方法以保持数据一致:变更设计
我放了一个简单易懂的样品。假设这个场景:
^{pr2}$现在,你想避免一个队和自己比赛,而a队只能和B队打一次(几乎是你的规则)。您可以将模型重新设计为:
ManyToManyField.symmetrical
这看起来像是一个symetrical问题,django可以为您处理。与其创建
GroupedModels
模型,只需在OtherModel
上创建一个ManyToManyField字段:这就是django为这些场景内置的。在
这不是一个非常令人满意的答案,但不幸的是,没有办法用一个简单的内置功能来实现您所描述的功能。在
您用
clean
描述的内容可以工作,但是您必须小心地手动调用它,因为我认为只有在使用ModelForm时才会自动调用它。您可能能够create a complex database constraint,但这将存在于Django之外,并且您必须处理数据库异常(这在Django中很难处理)。在也许有更好的方法来组织数据?在
相关问题 更多 >
编程相关推荐