Django - makemigrations - 未检测到更改

278

我试图使用makemigrations命令在现有应用程序中创建迁移,但它输出“未检测到更改”。

通常我使用startapp命令创建新的应用程序,但在创建此应用程序时没有使用它。

调试后,我发现它没有创建迁移,因为一个应用程序中缺少migrations包/文件夹。

如果没有这个文件夹,是否最好创建它,或者我漏掉了什么?


33
你是否已将你的应用程序添加到INSTALLED_APPS中? - wolendranh
21
是的,它是已安装的应用程序,第一次最好使用makemigrations <myapp>,正如Alasdair所指出的那样。 - Dilraj
3
去掉 'abstract = True' :) - GrvTyagi
4
“makemigrations” 无法工作。“makemigrations <myapp>” 可以工作。 - Aseem
6
我有同样的问题,原因是我忘记在 app/admin.py 中注册模型。 - Santi Rodriguez
显示剩余4条评论
40个回答

531
为某个应用程序创建初始迁移,请运行makemigrations并指定应用程序名称。将创建迁移文件夹。
./manage.py makemigrations <myapp>

你的应用程序必须首先被包含在INSTALLED_APPS中(在settings.py文件中)。


34
为什么他们有时会强制要求我们指定应用程序? - maazza
73
如果应用程序没有 migrations 文件夹,你需要指定应用程序的名称。这可能是因为你手动创建了该应用程序,或者从早期没有迁移的 Django 版本进行了升级。请注意,这里不涉及解释和其他内容。 - Alasdair
26
实际上,您需要在应用程序中使用名为'migrations'的Python包(带有__init__.py)。 - Jibin
6
听起来像是 Django 应该自动处理的事情。 - duality_
5
@duality_ ,这是有意设计的(is by design)- Django 不会默认为您的应用程序创建迁移。如果它为所有应用程序创建迁移,则在运行 migrate 时可能会导致错误。 - Alasdair
显示剩余3条评论

105
我的问题(以及解决方案)与上述描述的不同。我没有使用models.py文件,而是创建了一个名为models的目录,并在其中创建了my_model.py文件来放置我的模型。Django找不到我的模型,因此它写道没有要应用的迁移。我的解决办法是:在my_app/models/__init__.py文件中添加这一行:from .my_model import MyModel。

这对我来说也是解决方案,但我不明白为什么会这样。有人能提供一些关于可能原因的见解吗? - Paul in 't Hout
2
Django有默认的路径来查找您的模型。如果项目结构不同,并且模型不在通常的位置,则需要将它们导入到那里。 - Karina Klinkevičiūtė
1
@KarinaKlinkevičiūtė 如果我需要移除这些模型怎么办? - Danil
@DaniilMashkin 我想你也需要删除导入。这是组织项目的一种方式(不是唯一的方式),如果你选择它,你必须处理附带的额外任务 :) - Karina Klinkevičiūtė
3
我曾经使用过“传统”模型架构,后来迁移到了“模型文件夹”架构,并且任何迁移仍然被检测到我的现有模型上。但是,现在,在创建模型时,我遇到了这个问题。您的解决方案很有效,但它让我的代码库有点不一致,因为有时会有导入,有时则没有。也许有更好的解决方案。我猜Django应该提供一个设置,列出在查找新模型时要查找的文件夹列表。 - David Dahan
显示剩余2条评论

91
django在执行makemigrations命令时可能无法检测到需要迁移的内容,可能原因如下:
1. 迁移文件夹:需要在应用程序中创建一个迁移包。
2. INSTALLED_APPS: 应该在INSTALLED_APPS字典中指定应用程序。
3. 详细程度:可以通过运行“makemigrations -v 3”来增加详细程度。这可能会揭示问题所在。
4. 完整路径:建议在INSTALLED_APPS中指定完整模块应用程序配置路径"apply.apps.MyAppConfig"。
5. --settings: 确保设置了正确的设置文件: "manage.py makemigrations --settings mysite.settings"
6. 明确指定应用程序名称:将应用程序名称明确放在“manage.py makemigrations myapp”中,这样可以缩小应用程序的迁移范围,并帮助您隔离问题。
7. 模型元数据:检查模型元数据中是否有正确的app_label。
8. 调试django: 调试django核心脚本。makemigrations命令非常直截了当。以下是在pycharm中执行此操作的方法。根据需要更改脚本定义(例如:makemigrations --traceback myapp)。

多个数据库:

  • Db Router 在使用django db路由器时,路由器类(您的自定义路由器类)需要实现allow_syncdb方法。

makemigrations总是为模型更改创建迁移,但如果allow_migrate()返回False,则不会执行migrate操作。


3
涵盖了问题的许多情形,应该是被接受的答案。 - Krishh
1
另一个原因是确保模型在网站的路由中使用(通过管理员或其他方式)。“makemigrations脚本查找从urls.py连接的模型”。在此处找到:https://dev59.com/yKDia4cB1Zd3GeqPDnDm - Kyle
@user1134422 这是StackOverflow上对任何问题的最佳答案之一。它解决了许多人遇到的相同外观问题。谢谢你。 - Scott Stafford
我已经检查了所有的点,但它仍然不能正常工作。原来,在models.py中的数据模型类中缺少超类models.Model。也要检查一下这个! - Pink Flying Elephant
如果上面的列表没有帮助,请尝试在脑海中跟随您的代码通过记录的启动过程,并查看是否有任何线索。情况并不像你想象的那么糟糕;比整天没有迁移要好:https://docs.djangoproject.com/en/4.0/ref/applications/#how-applications-are-loaded这就是为什么魔法很糟糕。魔法应该隐藏您不需要知道的实现细节,但是使用Django时,每次您做一些有趣的事情,都需要深入了解魔法。这不是Pythonic的。总有一天,将不会有Django。 Django不是永恒的。 - NeilG
显示剩余4条评论

36

我已经阅读了许多回答这个问题的答案,通常是建议以某些其他方式运行makemigrations。但对我来说,问题在模型的Meta子类中。

我有一个应用程序配置,其中说标签= <应用程序名称>(在apps.py文件中,旁边是models.pyviews.py等)。如果您的元类与应用程序标签不同(例如因为您将一个太大的应用程序拆分成多个应用程序),则不会检测到任何更改(也没有任何有用的错误消息)。所以现在我的模型类中有:

class ModelClassName(models.Model):

    class Meta:
        app_label = '<app name>' # <-- this label was wrong before.

    field_name = models.FloatField()
    ...

这里正在运行Django 1.10。


如果您根本没有“Meta”,会发生什么情况?那么它默认会为“app_label”赋予什么值? - ArtOfWarfare

27

另一个导致此问题的原因是字段后面有逗号,这会导致在进行makemigrations时跳过该字段:

class MyModel(models.Model):
    name = models.CharField(max_length=64, null=True)  # works
    language_code = models.CharField(max_length=2, default='en')  # works
    is_dumb = models.BooleanField(default=False),  # doesn't work

我在一行代码中可能是从复制粘贴过来的,有一个拖尾的逗号,。有 is_dumb 的那一行不会创建模型迁移与./manage.py makemigrations,因为Python认为它是一个元组(tuple),而Django不认为它是一个字段。


2
末尾的逗号可能会在其他地方引起错误;逗号将语句变成了元组,所以 is_dumb 等于 (models.BooleanField(default=False), ),而 makemigrations 不知道如何将其转换为数据库列。 - hlongmore
这件事情发生在我身上,如果不知道该怎么做,应该是一个警示。 - Daniel Benedykt
是的,这个解决方案对我有效。 - mufazmi
天才!对我有用 - undefined

21
更新:在尝试以下命令之前,应确保migrations文件夹中存在一个__init__.py文件:

./manage.py makemigrations <myapp1> <myapp2> ... <myappN>


有时./manage.py makemigrations./manage.py makemigrations <myapp>更优越,因为它可以处理应用程序之间的某些冲突。

这些情况会默默地发生,需要数小时的咒骂才能了解可怕的“未检测到更改”消息的真正含义。

因此,最好使用以下命令:

./manage.py makemigrations <myapp1> <myapp2> ... <myappN>


1
调试了4个小时,结果问题就在这里!init.py 文件被添加到.gitignore中。本地文件存在,因此一切正常。当我推送到Heroku时,应用的迁移被忽略了!这样修复了它。 - Stormbytes

20

这是一条评论,但可能应该是一个答案。

请确保你的应用程序名称在 settings.py 的 INSTALLED_APPS 中,否则无论你做什么都无法运行迁移。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    'blog',
]

然后运行:

./manage.py makemigrations blog

但是当我们运行 'manage.py migrate' 命令时,它会将表名创建为'appname_modelname'。 - Daniyal Javaid
请参阅模型元选项以更改表名。 - tread

13

方法:1

步骤:1

确保您的应用程序在settings.py中的INSTALLED_APPS中被包含。

步骤:2

python manage.py makemigrations <appname>

如果出现相同的消息(未检测到更改)

!警告:这对您的项目非常危险,因此在应用方法2之前,请确保备份您的项目。

方法2

重命名您的应用程序名称并使用以下命令创建新应用程序:

django-admin startapp <appname>

复制所有的.py文件,除了旧应用程序中的:

  • migration文件夹
  • pycache文件夹
  • init.py
  • 如果你没有在test.py文件中编写代码,则将其排除在外


并将它们粘贴到你最近创建的新应用程序中。

记住,你必须确保新应用程序的名称完全相同,否则你将不得不在项目中进行更多的更改。


11

我曾经从Django外部复制了一个表格,结果Meta类的默认值是“managed=false”。例如:

class Rssemailsubscription(models.Model):
    id = models.CharField(primary_key=True, max_length=36)
    ...
    area = models.FloatField('Area (Sq. KM)', null=True)

    class Meta:
        managed = False
        db_table = 'RSSEmailSubscription'

managed改为True后,makemigrations开始捕获更改。


11

我的问题比上面的答案简单得多,而且可能是一个更常见的原因,只要您的项目已经设置好并且正常运行。在我的一个应用程序中,迁移似乎有点不稳定,所以匆忙之间,我做了以下操作:

rm -r */migrations/*
rm db.sqlite3
python3 manage.py makemigrations
No changes detected

什么??

我错误地删除了所有的__init__.py文件:( - 在我进去并进行以下操作后,一切都恢复正常:

touch ads1/migrations/__init__.py

对于我的每个应用程序,makemigrations 现在又可以工作了。

事实证明,我手动复制了另一个应用程序创建了一个新的应用程序,但忘记将 __init__.py 放在 migrations 文件夹中,这让我觉得一切都错了 - 最终导致我像上面描述的那样更糟糕地使用了 rm -r 命令。

希望这能帮助某个人避免在 "未检测到任何更改" 错误前 swear 几个小时。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接