Django一对多字段没有逆转依赖

时间:2014-09-03 02:43:17

标签: django

有很多地方建议将ForeignKey用于一对多或多对一的关系,但我很难理解如何在没有逆转依赖的情况下实现这一点。

例如:

我有这2个应用,'和解'和付款'理想情况下,和解协议不需要了解付款,因为付款记录是在结算后创建的,而付款记录可能包含多个和解。

和解模式:

class Settlement(models.Model):
    ...

付款模式:

class Payment(models.Model):
    settlements = models.ManyToManyField('Settlement')
    ....

这带来了基本的模式警告,即结算可以属于多次付款,这不应该发生。

要强制执行结算不能属于多个付款记录,我必须将付款foreignkey放入结算中:

和解模式:

class Settlement(models.Model):
    payment = models.ForeignKey('Payment')
    ...

付款模式:

class Payment(models.Model):
    ....

虽然这会强制执行架构有效性,但似乎依赖性已经逆转,现在解决方案需要了解付款,只是让这两个应用程序紧密耦合。此外,我需要创建一个结算记录,其中付款字段为空,创建付款记录,然后返回到结算记录以链接付款记录,这似乎是错误的。

2 个答案:

答案 0 :(得分:2)

虽然在Settlement上有一个链接到Payment的外键可能有意义,但您的应用程序不必具有该关系(或在数据库上强制执行) 。我将假设Settlement无法更改,并且您只能使用Payment应用。

只需创建您自己的中间模型/表格,然后将 与付款相关联即可。它就像拥有ManyToMany关系,但你可以强制执行约束。

class Payment(models.Model):
   # your fields go here

class Invoice(models.Model):
    settlement = models.OneToOneField('settlements.Settlement')
    payment = models.ForeignKey(Payment)

请注意OneToOneField。这基本上是具有唯一约束的外键。我们正在模拟ManyToMany中间表,但将settlement限制为只在发票表中包含一条记录。

我应该注意,因为我们在这里创建了一个新表,由于需要额外的连接,未来的查询可能会很慢。如果您修改Settlement模型以包含ForeignKey,它将从标准化意义上执行并且看起来更好。

答案 1 :(得分:1)

我的一位同事发现了这个项目:

https://github.com/adsworth/django-onetomany

它在manytomany关系中添加了一个独特的约束。