【问题标题】:Why use apps.get_model() when creating a data migration?为什么在创建数据迁移时使用 apps.get_model()?
【发布时间】:2016-10-12 10:17:54
【问题描述】:

根据 django 文档,在创建 django 迁移时,我们应该使用 apps.get_model() 而不是导入模型并使用它们。

为什么数据迁移必须使用模型的历史版本而不是最新版本?(模型的历史版本无论如何都不会被使用,对吧?)

【问题讨论】:

    标签: django-models django-migrations


    【解决方案1】:

    它使用模型的历史版本,因此当您对另一个数据库运行迁移时,它不会在尝试访问代码库中可能不再存在的字段时遇到问题。

    如果您从模型中删除了某些字段,然后想在某个新数据库上运行迁移,并且您直接导入模型,您可以预期您的迁移会抱怨尝试使用不存在的字段。当使用apps.get_model(...) 时,Django 会尝试变得聪明,并使用你的迁移文件中的migrations.AddField(...) 的定义来及时为你提供模型的正确版本。

    这也是 Django 说在数据迁移中使用自定义模型/模型管理器方法要小心的原因,因为我不相信他们可以从迁移历史中重新创建这些方法,或者行为会随着时间和迁移而改变不会是一致的。

    【讨论】:

    • 如果我删除模型中的字段,我希望我的迁移只关注存在的字段,而不是删除的字段。所以当 django 抱怨我试图使用一个不存在的字段时,那是希望我们期望 django 抱怨正确吗?
    • Django 可能是在谈论 6 个月前编写的数据迁移,当时模型完全不同,但现在数据迁移仍然需要像 6 个月前一样工作。它不应该抱怨当前模型中缺少字段,因为数据迁移不是为当前模型设计的,而是为特定版本的模型设计的。
    • 谢谢!太笨了,我想不出这种情况
    【解决方案2】:

    考虑这个模型:

    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。否则会报错。

    【讨论】:

      猜你喜欢
      • 2021-06-17
      • 2021-10-27
      • 1970-01-01
      • 2013-10-08
      • 1970-01-01
      • 2019-12-20
      • 2016-02-28
      • 1970-01-01
      • 2020-09-25
      相关资源
      最近更新 更多