在自定义迁移中将模型导入为“apps.get_model('app_name', 'ModelName')”的逻辑是什么

unl*_*kme 2 django import django-migrations

我问这个问题是因为当我使用使用MPPT模型的django-hordak时,我遇到了django.db.utils.IntegrityError: null value in column \xe2\x80\x9clft\xe2\x80\x9d违反非空约束

\n\n

提出的一些解决方案虽然hacky违背了惯例,但确实有效。

\n\n

基础

\n\n

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

\n\n
def forward_func(apps_registry, schema_editor):\n    Model = apps_registry.get_model(\'app_name\', \'ModelName\')\n    Model.objects.create(**{\'field_1\': \'field_1\', \'field_2\': \'field_2\')\n    # Do whatever you want with my Model \n
Run Code Online (Sandbox Code Playgroud)\n\n

在我的情况下,django-hordak 具有帐户模型。.objects.create(**data)\nraises the上面指定的数据库上的 IntegrityError 。

\n\n

建议的解决方案

\n\n

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

\n\n
def forward_func(apps_registry, schema_editor):\n    # Model = apps_registry.get_model(\'app_name\', \'ModelName\')\n    # lets forget about importing the standard way because it will raise integrity error.\n\n    from app_name.models import ModelName as Model\n    # Now we can proceed to deal with our model without Integrity Error.\n    Model.objects.create(**data)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这让我担心直接在迁移文件中导入模型可能会产生不良副作用。

\n\n

因为模型没有以这种方式导入迁移文件中肯定有很好的理由。

\n\n

我并不是在寻找MPTT模型在以标准方式导入时失败的原因,因为这个问题在这里有答案。.\n我特别想了解迁移文件中使用的导入模型背后的逻辑apps.get_model

\n

cod*_*joe 5

这是一个非常好的问题,因为确实存在很大的差异。

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

这就是为什么有apps.get_model。它将为您提供一个基于先前迁移定义的状态的“虚拟”模型。请注意,这与代码中的模型不同。它没有您实现的任何自定义函数和行为,除非它们是 ORM API 的一部分。换句话说,主要是字段和元选项,例如 ordering 和 co。

另请注意,正确的签名apps不是app_registry。它不应与 中的应用程序注册表混淆django.apps.apps。它也有一个get_model方法。然而,这将返回当前代码中的模型。

我知道一开始(甚至后来)可能会有点混乱。我建议遵循一个简单的规则。不要将您自己的任何代码导入到迁移中。如果必须的话,将行为向后移植到迁移中。

我希望这种区别对你有一点帮助。如果您还有其他问题,请给我留言。我很高兴扩展我的答案。

最好的-乔