【发布时间】:2016-10-12 10:17:54
【问题描述】:
根据 django 文档,在创建 django 迁移时,我们应该使用 apps.get_model() 而不是导入模型并使用它们。
为什么数据迁移必须使用模型的历史版本而不是最新版本?(模型的历史版本无论如何都不会被使用,对吧?)
【问题讨论】:
标签: django-models django-migrations
根据 django 文档,在创建 django 迁移时,我们应该使用 apps.get_model() 而不是导入模型并使用它们。
为什么数据迁移必须使用模型的历史版本而不是最新版本?(模型的历史版本无论如何都不会被使用,对吧?)
【问题讨论】:
标签: django-models django-migrations
它使用模型的历史版本,因此当您对另一个数据库运行迁移时,它不会在尝试访问代码库中可能不再存在的字段时遇到问题。
如果您从模型中删除了某些字段,然后想在某个新数据库上运行迁移,并且您直接导入模型,您可以预期您的迁移会抱怨尝试使用不存在的字段。当使用apps.get_model(...) 时,Django 会尝试变得聪明,并使用你的迁移文件中的migrations.AddField(...) 的定义来及时为你提供模型的正确版本。
这也是 Django 说在数据迁移中使用自定义模型/模型管理器方法要小心的原因,因为我不相信他们可以从迁移历史中重新创建这些方法,或者行为会随着时间和迁移而改变不会是一致的。
【讨论】:
考虑这个模型:
class A(models.Model):
field1 = models.PositiveIntegerField()
field2 = models.PositiveIntegerField()
您的迁移历史知道这两个字段,并且任何进一步的迁移都会考虑此模型状态并对此模型状态进行更改。
现在假设,您删除 field1,您的模型变为:
class A(models.Model):
field2 = models.PositiveIntegerField()
并且在迁移中,你尝试使用 field1,django 应该知道 field1 存在。因此,当我们使用apps.get_model() 时,它可以帮助 django 使用以前的迁移历史并推断 field1。否则会报错。
【讨论】: