我关注了这篇文章here,并整理了如何将一个模型的ForeignKey设置为另一个应用程序中的模型。但是,当我第二次尝试时,我会收到错误并且不确定原因。
我的中央应用程序包含“项目”和“注释”的模型,以及带有报告模型的报告应用程序。 “注释”在“报告”应用中的“报告”中有一个FK,这似乎可以正常使用此代码:
#models.py for Central app
from GIanno.pt_reports.models import Report
class annotation(models.Model):
...
report=models.ForeignKey(Report)
但是,在Reports应用程序中,当我尝试为“报告”设置FK以使用与上面相同的格式将其链接到“中心”应用程序中的“项目”时,我收到错误“无法导入从导入行命名'project'。
关于它为什么以某种方式工作而不是另一种方式的任何想法。订单有点重要吗?感谢
答案 0 :(得分:8)
我的猜测是你创建了一个循环导入条件。当你从一个python模块导入一些东西时会发生这种情况,而python模块又从试图导入它的模块导入,从而阻止了导入的解析。
一般来说,处理循环导入有三种策略,其中两种在这种情况下有效:
移动您的类和导入,以便导入只朝一个方向。
使用延迟评估。在Django的情况下,可以通过使用点表示法传递指定应用程序名称和模型的字符串来为ForeignKey完成此操作:report=models.ForeignKey('central.Report')
将import语句移出全局模块范围,并移入模块中函数的范围。这样,导入不会立即进行评估,并且模块可以作为一个整体成功导入,同时仍允许模块中的导入在调用时发生。 (注意:这不适用于ForeignKey关系)
懒惰的FK分辨率(#2)可能是你最好的选择。一般而言,尽管最好的策略是简化模型/模块布置,以尽可能避免循环导入。
答案 1 :(得分:1)
尝试:
class annotation(models.Model):
...
report=models.ForeignKey('centralapp.Report')
将'centralapp'替换为您的中央应用名称,而无需导入。
答案 2 :(得分:0)
Lazy Relationships可能有用的另一种情况是导入顺序。它不是一个循环引用(它不能告诉谁是第一个),而是一个代码在另一个代码之前加载的情况。
例如,假设我有一个Doc模型和一个Log Model。 Log模型具有Doc的FK,因此我可以记录文档中的更改。这样可以正常工作,比方说,我尝试在我的Doc模型的save方法中生成一条日志记录(用于创建保存事件日志条目)。在这种情况下,Doc对象中没有Log PK,但是类似的问题。
在这种情况下,您会遇到导入订单问题,其中一个会尝试引用尚未加载到Python中的内容。它与循环参考类似,但原因不同。
这可以通过其他方式解决,但另一个例子就是遇到这个问题。