使用像
这样的东西是否有任何缺点from django.db.models.loading import get_model
def get_something():
model = get_model('app', 'Model')
return model.something()
而不是
from app.models import Model
def get_something():
return Model.something()
第二个例子可以导致循环依赖,而第一个例子没有,但第二个例子更常见。
更新:如果第二个示例位于名为Other_Model的模型中,并且模型导入了Other_Model,则会出现循环依赖性错误 - 这是一个简单的循环导入。
答案 0 :(得分:12)
通常,get_model
功能保留用于需要动态加载模型的时间(例如,如果您不知道是否有人将服务传递给myapp.Person,myapp.Place,或者一个myapp.Thing,它们都有相同的界面)。我甚至会说,除非引入意外情况,否则任何其他用途都应该在代码审查中自动标记。
至于内部机制,确实没有实质性差异。 get_model
版本不可避免地会调用__import__
。那就是it is not without bugs。使用实际的import
语句可以避免这个问题。
关于MRO问题,通过重构无法解决循环导入的罕见情况。如果你有两个相互依赖的应用程序导致循环导入,那么你真的需要重新考虑这些应用程序。 (我的猜测是你真的在处理一个应用程序。)
答案 1 :(得分:5)
如果您的应用路径不是那么直接,则使用get_model
可能会造成混淆。
例如,如果您的模型存在于apps.MyApp.models.misc.MyModel
中,那么调用将是get_model('MyApp', 'misc.MyModel')
,这不是太直观。你可能不得不通过反复试验或深入研究来源来解决这个问题。
(请注意,这适用于Django 1.6及之前的版本.Django 1.7+对应用程序命名有很多变化,这可能已经改变了)
避免循环依赖的另一种方法是直接在方法中导入,如下所示:
def get_something():
from app.models import Model
return Model.something()
这将推迟导入,直到第一次调用方法。