django - 在自定义迁移中将模型导入为 `apps.get_model('app_name', 'ModelName')` 的逻辑是什么
问题描述
我问这个问题是因为我遇到了这个django.db.utils.IntegrityError: null value in column “lft”当我使用使用MPPT模型的 django-hordak时违反了非空约束。
提出的一些解决方案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 使用帐户模型。上面.objects.create(**data)
raises the
指定的数据库上的 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模型在导入标准方式时失败的原因,因为该问题在这里有答案。. 我想特别了解apps.get_model
在迁移文件中使用导入模型背后的逻辑。
解决方案
这是一个很好的问题,因为确实有很大的不同。
如果您导入模型,您将获得模型代码中当前定义的任何内容。但是如果你想删除一个模型会发生什么?您如何确保您的迁移仍然有效?
这就是为什么有apps.get_model
. 它将根据先前迁移定义的状态为您提供“虚拟”模型。请注意,这与代码中的模型不同。它没有您实现的任何自定义函数和行为,除非它们是 ORM API 的一部分。换句话说,主要是字段和元选项,例如 ordering 和 co。
另请注意,正确的签名apps
不是app_registry
. 它不应与django.apps.apps
. 它也有一个get_model
方法。但是,这将在您当前的代码中返回模型。
我知道一开始(甚至后来)可能会有点混乱。我建议遵循一个简单的规则。不要将您自己的任何代码导入迁移。如果必须,将行为反向移植到迁移中。
我希望这种区别对您有所帮助。如果您还有其他问题,请给我留言。我很高兴扩展我的答案。
最佳-乔
推荐阅读
- c# - 创建新 Telerik DataSource 实现时出现问题:“不实现继承的抽象成员 'DataSource.CreateClone()'”
- linux - 以自动方式从网页下载数据
- html - 如何在 Angular2 模板驱动表单中触发错误/使用哪个验证器来检查输入字段是否没有值
- slideshow - fancybox3,如何在幻灯片图像上制作圆角
- javascript - 使用 `value` 键并在条件 `classname` React 中使用
- windows - 如何使用批处理脚本根据.txt文件内容将文件复制到不同的地方
- curl - 无法在 AWS API Gateway 上执行 POST 请求
- java - Java中非均匀分布的随机数生成
- excel - Outlook .VotingOptions = 不再工作
- python - Python Pandas - 从网站读取数据的问题