InvalidBasesError: Cannot resolve bases for [<ModelState: 'users.GroupProxy'>]

InvalidBasesError: Cannot resolve bases for [<ModelState: 'users.GroupProxy'>]

当我 运行 测试时,我在数据库初始化期间遇到此错误:

django.db.migrations.state.InvalidBasesError: Cannot resolve bases for [<ModelState: 'users.GroupProxy'>]
This can happen if you are inheriting models from an app with migrations (e.g. contrib.auth)

我为 contrib.auth 组模型创建了这个代理,以便将它放在我在 django 管理中的应用程序中:

class GroupProxy(Group):
    class Meta:
        proxy = True
        verbose_name = Group._meta.verbose_name
        verbose_name_plural = Group._meta.verbose_name_plural

那么我该怎么做才能解决这个问题?

在 运行 测试之前,您是否在您的应用上尝试过 运行 manage.py makemigrations <app_label>

此外,请检查您尝试代理的应用模型是否包含在您的 INSTALLED_APPS 中。

经过大量挖掘后,唯一对我有用的是

comment out the offending apps, run migrations, then add them in again.

只是一个变通方法,但希望它对某人有所帮助。

如果这仅在 运行 python manage.py test 时发生(可能是因为您已经进行了必要的迁移),您应该明确说明 contrib.auth 不应在 MIGRATION_MODULES 你的设置模块。

MIGRATION_MODULES(
        'auth': "contrib.auth.migrations_not_used_in_tests",
)

我遇到过这个问题,由于注释掉模型并不是真正的解决方案,我发现将未记录的 auto_created = True 设置为 Meta class 将使 Django忽略它。

class GroupProxy(Group):

    class Meta:
        proxy = True
        auto_created = True

我在重命名我的一堆代理模型的父 table 后遇到了这个问题。我通过以下方式解决了它:

  1. 正在删除为父 table 更改名称的迁移文件。
  2. 使用 postgres 终端,我将父 table 重命名为其以前的名称。
  3. 运行 makemigrationsmigrate

只需在您的应用程序的根目录创建一个 migrations 目录(在您的情况下为 users/migrations/)并添加一个空的 __init__.py 文件可能会解决您的问题。至少当我遇到同样的错误时它对我有用。

但是你最好 运行 makemigrations 为你的应用程序,如建议 @zenofewords 以上。这将为您创建目录并为您的代理模型生成迁移。

您的测试正在寻找这些迁移,但没有找到它们。

我也遇到过这个问题(在做了一些复杂的模型继承之后)。我的一个迁移包含

migrations.CreateModel(
    name='Offer',
    fields=[
        # ...
    ],
    options={
        # ...
    },
    bases=('shop.entity',),
),

我完全删除了 shop.Entity 模型,但迁移在 bases 属性中引用了它。所以我刚刚删除了 bases=('shop.entity',) 并且它有效。它可能会打破从一开始就迁移的机会,但至少允许进一步迁移。

另一个建议是:直接转到 django 代码并检查导致 "bases" 问题的原因。转到 django/db/migrations/state.py 并添加断点:

try:
    bases = tuple(
        (apps.get_model(base) if isinstance(base, six.string_types) else base)
        for base in self.bases
    )
except LookupError:
    print(self.bases)  # <-- print the bases
    import ipdb; ipdb.set_trace()  # <-- debug here
    raise InvalidBasesError("Cannot resolve one or more bases from %r" % (self.bases,))

今天下午的大部分时间都在尝试自己解决这个错误,检查了所有可能的 'commenting out apps'、'dropping tables' 组合并删除了整个数据库,我发现我的问题是由一个简单的问题引起的所述文件夹内缺少 'migrations' 文件夹和 __ init__.py 文件。

一个较早的正确答案现在不再正确,因为他们已经解决了提到的问题 here

检查每个包含 'init.py' 中提到的模型的目录,它应该消失。

可能不会解决每个人的问题,但它帮助了我。

一种可能是迁移文件中模型的删除或创建顺序错误。当基本模型在派生模型之前时,我在 Django 1.7.8 中遇到过这种情况。交换删除模型的顺序解决了问题。

发生在我​​身上没有其他应用程序 - 只是因为我重命名了一个模型,该模型是其他模型的基础(并且可能在同一迁移中创建了该子模型)将超级模型重命名为它的原始名称解决了它对我来说

我遇到了同样的问题,在 class Meta: 中添加 app_label 属性解决了错误:

class GroupProxy(Group):
    class Meta:
        proxy = True
        app_label = '<app in which you want this model>'
        verbose_name = Group._meta.verbose_name
        verbose_name_plural = Group._meta.verbose_name_plural

如果您在已有迁移文件夹(以及其中的 init.py 文件)的应用程序中出现这种情况,请删除所有其他文件,然后 运行 makemigrationsmigrate 再次。

P.S.: 您可能需要手动重新配置 models.py 或数据库中的某些表。

万一有人犯了和我一样的错误,我遇到了同样的问题,因为我没有对代理模型进行任何迁移。这对我来说似乎没有必要,因为他们没有自己的数据库表,而且我在文档中也没有看到任何提及这一点的内容。 python manage.py makemigrations <APP_NAME> 马上修好了。

添加名为“migrations”的文件夹,并在该文件夹中创建“__init__.py”文件

有一个相关的问题。在这里查看我的回答

TL;DR

创建您自己的移除碱基的操作

class RemoveModelBasesOptions(ModelOptionOperation):
    def __init__(self, name):
        super().__init__(name)

    def deconstruct(self):
        kwargs = {
            'name': self.name,
        }
        return (
            self.__class__.__qualname__,
            [],
            kwargs
        )

    def state_forwards(self, app_label, state):
        model_state = state.models[app_label, self.name_lower]
        model_state.bases = (models.Model,)
        state.reload_model(app_label, self.name_lower, delay=True)

    def database_forwards(self, app_label, schema_editor, from_state,
                          to_state):
        pass

    def database_backwards(self, app_label, schema_editor, from_state,
                           to_state):
        pass

    def describe(self):
        return "Remove bases from the model %s" % self.name

    @property
    def migration_name_fragment(self):
        return 'remove_%s_bases' % self.name_lower

对于没有迁移的应用,您可能需要 运行 makemigrations

在我的例子中 django_quiz 取决于 multichoicetrue_falseessay

我必须先 makemigrations 才能 migrate django_quiz.