Django 在自定义迁移中,将模型导入为“apps.get”model(';app#u name';,';ModelName';)的逻辑是什么

Django 在自定义迁移中,将模型导入为“apps.get”model(';app#u name';,';ModelName';)的逻辑是什么,django,import,django-migrations,Django,Import,Django Migrations,我问这个问题是因为我在使用django-hordak时遇到了这个问题,它使用MPPT模型 提出的一些解决方案是“黑客式”的,因为它们违背了通常的做法,但很有效 基础知识 在django中编写自定义迁移时,例如在创建基线数据时 def forward_func(apps_registry, schema_editor): Model = apps_registry.get_model('app_name', 'ModelName') Model.objects.create(**{

我问这个问题是因为我在使用django-hordak时遇到了这个问题,它使用MPPT模型

提出的一些解决方案是“黑客式”的,因为它们违背了通常的做法,但很有效

基础知识

在django中编写自定义迁移时,例如在创建基线数据时

def forward_func(apps_registry, schema_editor):
    Model = apps_registry.get_model('app_name', 'ModelName')
    Model.objects.create(**{'field_1': 'field_1', 'field_2': 'field_2')
    # Do whatever you want with my Model 
在我的情况下,django hordak使用帐户模型。创建(**数据) 如上所述,在数据库上引发IntegrityError

建议的解决方案

建议的解决方案之一是直接导入模型

def forward_func(apps_registry, schema_editor):
    # Model = apps_registry.get_model('app_name', 'ModelName')
    # lets forget about importing the standard way because it will raise integrity error.

    from app_name.models import ModelName as Model
    # Now we can proceed to deal with our model without Integrity Error.
    Model.objects.create(**data)
这让我害怕直接在迁移文件中导入模型可能带来的不良副作用

因为必须有很好的理由来解释为什么模型不能以这种方式导入到迁移文件中

我不是在寻找MPTT模型在以标准方式导入时失败的原因,因为这个问题有一个。
我想特别了解使用
应用程序导入模型背后的逻辑。在迁移文件中获取模型。

这是一个非常好的问题,因为实际上有很大的区别

如果您导入一个模型,您将获得当前在模型代码中定义的任何内容。但是,如果要删除模型,会发生什么情况?如何确保迁移仍然有效

这就是为什么会有
应用程序。获取_model
。它将根据以前的迁移定义的状态为您提供一个“虚拟”模型。请注意,这与代码中的模型不同。它没有您实现的任何自定义函数和行为,除非它们是ORMAPI的一部分。换句话说,主要是字段和元选项,如排序和co

还请注意,正确的签名是
apps
而不是
app\u注册表
。不应将其与
django.apps.apps
中的应用程序注册表混淆。它还有一个
get\u model
方法。但是,这将在当前代码中返回模型

我知道一开始(甚至后来)可能会有点困惑。我建议遵循一个简单的规则不要将自己的任何代码导入迁移。如果必须,请将后端口行为导入迁移。

我希望这种区别能对你有所帮助。如果您还有其他问题,请给我留言。我很高兴回答这个问题

最好的
-乔

请参阅。TL;DR:在创建迁移时,注册表包含模型的冻结版本,这可能与现在完全不同。感谢@Daniel Roseman查阅文档。如果你能写下答案让我接受。会有帮助的。我认为你的答案很好。您是否可以包括一个场景,例如将模型从应用程序a移动到应用程序B,并解释如何失败。我已经知道会发生什么了。只要一个例子就可以改善答案。@unlockme好的一点,我实际上想写
remove
而不是move。我更新了我的答案。我是否应该再加上一个例子呢?一个例子是好的,但对于一个对自己的行为有理性的人来说,这就足够了。