首页 > 解决方案 > Django 数据库迁移随着“元”类的添加而停止

问题描述

我创建了一个 Django 应用程序,我有一个这样的模型:

class Company(models.Model):
    name = models.TextField(max_length = 200)

当我运行时python3 manage.py makemigrations appname,一切都按预期工作,并为该类创建了一个迁移文件。

如果模型中的类也定义了一个Meta类,则会出现问题:

class Company(models.Model):
    name = models.TextField(max_length = 200)
    class Meta:
        app_label = "Companies"

现在,如果我运行该makemigrations命令,我会收到“未检测到更改”消息,并且不会生成迁移文件:

> python3 manage.py makemigrations myApp
No changes detected in app 'appname'

或者,更糟糕的是,如果具有Meta该类的模型没有依赖项(外键),则会创建一个迁移,该迁移将完全删除模型/表。

或者,如果存在依赖项(来自另一个模型的外键引用),我会收到如下错误:

matcher.OtherTable.foreignkeyref: (fields.E300) Field defines a relation with model 'Company', which is either not installed, or is abstract.

由于某种原因,所有定义了Meta类的模型都不会生成迁移,无论是初始迁移还是任何后续迁移。事后添加了 Meta 的类将在下一次迁移时被删除。就好像它们根本不存在一样。

我在 Mac OS 10.15.5 上使用 Python 3.8.3 和 Django 3.0.6。

标签: pythondjangodjango-3.0

解决方案


由于某种原因,所有定义了Meta类的模型都不会生成迁移,无论是初始迁移还是任何后续迁移。Meta事后添加的类将在下次迁移时删除。

那么问题是你改变了app_label,现在你说这个模型不属于它最初属于的应用程序,而是其他地方。所以对于那个应用程序,模型已经“消失”,而对于一个新应用程序(Companies在这里),它似乎是“凭空出现的”。正如文档中指定的那样,使用app_labelwhen:

如果模型是在 INSTALLED_APPS 中的应用程序之外定义的,它必须声明它属于哪个应用程序 (...)。

指定app_label. 如果你不指定它,它会使用定义它的应用程序的名称。

但是,您似乎覆盖了错误的设置。根据您传递的值,您可能希望指定verbose_name_plural选项 [Django-doc]

class Company(models.Model):
    name = models.TextField(max_length = 200)

    class Meta:
        verbose_name_plural = "Companies"

推荐阅读