【问题标题】:Django App Dependency CycleDjango 应用程序依赖循环
【发布时间】:2010-10-28 02:00:23
【问题描述】:

我正在开发一个 Django 应用程序,该应用程序具有相当复杂的模型(它为一所大学建模 - 课程、模块、讲座、学生等)

我已将项目分成应用程序,以使整个事情更有条理(应用程序是课程、学校、人员、模块和时间段)。我遇到了一个问题,一个应用程序中的模型可能依赖于另一个应用程序中的模型 - 所以我必须导入它。然后第二个应用又依赖于第一个中的模型,因此有一个循环,Python 会抛出一个错误。

人们如何处理这个问题?我知道应用程序应该相对“独立”,但在这样的系统中,使用 ContentTypes 将学生链接到模块是没有意义的。

有没有人有类似的项目可以评论这个案例?

【问题讨论】:

  • 您的场景听起来不像是为应用而设计的场景。应用程序的理念是可重用性(以及单独的打包、分发和版本控制)。不要将您的主题区域强制放入单独的应用程序中,您可能会省去一些麻烦。

标签: python django dependencies


【解决方案1】:

如果您的依赖项是外键引用其他应用程序中的模型,您不需要导入其他模型。您可以在 ForeignKey 定义中使用字符串:

class MyModel(models.Model):
    myfield = models.ForeignKey('myotherapp.MyOtherModel')

这样就不需要导入MyOtherModel,所以没有循环引用。 Django 在内部解析字符串,一切都按预期工作。

【讨论】:

  • 太棒了。这正是我一直在寻找的。有趣的是,我知道你可以做到这一点 - 因为我在 ForeignKey 引用文件中稍后定义的内容的地方使用它,但我从未想过以这种方式使用它。非常感谢!
  • 在我找到你的帖子之前,我一直在尝试让模型进行验证。它给我的只是错误:无法导入名称 谢谢!
  • 这修复了在管理员中删除具有 FK 关系的对象时出现的问题。在完成删除之前,我必须手动删除相关对象,这修复了它。谢谢
【解决方案2】:

这可能不太适合您的情况,但忽略您的问题的 Django 方面,打破循环依赖关系的一般技术是将交叉引用的项目之一分解为新模块。例如:

moduleA: class1, class2
           |        ^
           v        |
moduleB: class3, class4

可能变成:

moduleC: class 3
           ^
           |
moduleA: class 1, class 2
                     ^
                     |
moduleB:          class 4

(或者,您也可以将第 2 类分解成它自己的模块。或者两者兼而有之!)

当然,如果 A 类和 B 类相互依赖,这将无济于事。在这种情况下,也许它们应该在同一个模块中,或者更好的是,也许这些类的某些部分可以分解为第三个模块,这两个类都依赖于它。

【讨论】:

    【解决方案3】:

    如果您看到循环模型依赖,我猜测正在发生以下三件事之一:

    • 您已定义与已定义的反向关系(例如,两门课程都有很多讲座,而讲座有一门课程),这在 django 中是多余的
    • 您在错误的应用中使用了模型方法
    • 您在模型方法中提供功能,而该模型方法应该在管理器中

    也许您可以向我们展示这些模型中发生了什么,我们可以尝试找出问题出现的原因。循环模型依赖性很少表明您需要组合两个应用程序 - 更有可能(尽管并非绝对如此)您的模型定义之一存在问题。

    附言我 am 正在开发一个类似的 django 应用程序,但我的应用程序结构可能与您的完全不同。如果您有兴趣,我很乐意为您提供高级别的描述。

    【讨论】:

    • 有趣。我遇到的详细问题是模块(模块应用程序)有一个外键到人(人员应用程序),供其学生使用。 people 应用程序中的 TutorGroup 然后有一个 ForeignKey 到 Module - 将一个导师组分配给一个特定的模块。这就是导致依赖循环的原因。如果还不清楚,我也可以发布模型图。我很想看看你的项目的总体结构——看看别人是怎么做的真的很有用。
    • Module 和 Person 之间的关系是多对多(似乎应该是)?如果是这样,您可以在 Person 中定义关系,并将 related_name 参数设置为“students”。然后 module_instance.students.all() 会给你我认为你正在寻找的查询集。就我而言,我没有 Person 模型。我有两个从课程到用户的 m2m 关系,一个用于学生,另一个用于教师。保持超级简单。
    • 是的,它目前可以与 ManyToManyField 一起使用——我可以将它移至 Person 模型——但它看起来不那么“整洁”——将它放在 Module 模型上是有意义的。我必须有一个“人”,因为它扩展了 Django 的用户,所以我可以添加更多功能(如职位描述等) /跨度>
    【解决方案4】:

    通常我主张将功能拆分为较小的应用程序,但模型之间的循环依赖反映了如此紧密的集成,以至于您可能不会从拆分中获得太多收益,可能会考虑合并应用程序。如果这导致应用感觉太大,则可能有一种方法可以沿不同的轴进行拆分,从而产生更合理的依赖关系图。

    【讨论】:

      猜你喜欢
      • 2011-06-14
      • 1970-01-01
      • 2019-06-04
      • 2013-07-16
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多