Django 一对多字段没有反向依赖

标签 django

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

例如:

我有这两个应用程序,“结算”和“付款”,理想情况下,结算不需要知道付款,因为付款记录是在结算后创建的,并且付款记录可以包含多个结算。

定居点模型:

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):
    ....

虽然这强制了模式有效性,但似乎依赖性已经逆转,现在结算需要了解付款,只是使这两个应用程序紧密耦合。另外我需要创建一个payment字段为空的结算记录,创建支付记录,然后返回到结算记录链接支付记录,这似乎是错误的。

最佳答案

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

只需创建您自己的中间模型/表,并将其与付款联系起来。这就像有一个多对多的关系,但你可以对它施加约束。

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

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

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

我可能应该注意到,因为我们在这里创建了一个新表,由于需要额外的连接, future 的查询可能会很慢。如果修改 Settlement模型包含一个外键,从规范化的角度来看,它会表现得更好,看起来更好。

关于Django 一对多字段没有反向依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25635408/

相关文章:

python - Django抛出错误 'WSGIRequest'对象没有属性 'push'

javascript - 确保当用户返回页面而不刷新时,由 javascript 更改的元素保持更改

django - Celery 与 Django 和 MongoDB (mongoengine)

python - 尝试组织我的网址

javascript - Django - 使用 JS window.open() 函数时将参数传递给 GET 方法

python - django get_or_create - 对象列表的性能优化

python - 对 Django 通用 View 有点困惑

python - Django - 确定传递给模板标签的变量的字段类型

python - 在 Django 中使用 Celery 设置结果后端 (rpc)

python - 使用 mysql2pgsql 将数据库从 MySql 传输到 Postgres 时出错