【问题标题】:Whats the logic of importing models as `apps.get_model('app_name', 'ModelName')` in a custom migration在自定义迁移中将模型导入为 `apps.get_model('app_name', 'ModelName')` 的逻辑是什么
【发布时间】:2019-12-02 16:06:49
【问题描述】:

我问这个问题是因为我在使用 django-hordak 时遇到了这个django.db.utils.IntegrityError: null value in column “lft” violates not-null constraint,它使用了 MPPT 模型。

提出的一些解决方案是hacky,因为它们违反了常规做法,但它们确实有效。

基础知识

在 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 使用帐户模型。上面指定的 DB 上的 .objects.create(**data) raises theIntegrityError。

建议的解决方案

提出的解决方案之一是直接导入模型。

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 模型在导入标准方式时失败的原因,因为该问题有一个 answer here。 . 我特别想了解在迁移文件中使用apps.get_model 导入模型背后的逻辑。

【问题讨论】:

  • full explanation。 TL;DR:注册表包含创建迁移时模型的冻结版本,这可能与现在完全不同。
  • 感谢@Daniel Roseman,查看了文档。如果你能写出被接受的答案。会有帮助的。

标签: django import django-migrations


【解决方案1】:

这是一个很好的问题,因为确实有很大的不同。

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

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

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

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

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

最好的 -乔

【讨论】:

  • 我觉得你的回答很好。您能否包括一个场景,例如将模型从 App A 移动到 App B,并解释它是如何失败的。我已经可以看到它会如何了。只是一个插图会改善答案。
  • @unlockme 好点,我其实想写remove 不动。我更新了我的答案。我还应该为此添加一个示例吗?
  • 举个例子就好了,但这对于一个对自己所做的事情有理性的人来说已经足够了。
猜你喜欢
  • 2016-09-29
  • 2016-10-12
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-18
相关资源
最近更新 更多