InvalidBasesError:无法解析[<modelstate:'users.groupproxy'=“”>]的基数

时间:2015-05-15 19:21:11

标签: python django unit-testing django-models django-migrations

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

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 admin中的应用程序中:

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

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

15 个答案:

答案 0 :(得分:21)

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

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

只是一种解决方法,但希望它可以帮助某人。

答案 1 :(得分:15)

我遇到过这个问题,并且评论模型并不是一个真正的解决方案,我发现将未记录的auto_created = True设置为Meta类将使Django成为可能忽略它。

class GroupProxy(Group):

    class Meta:
        proxy = True
        auto_created = True

答案 2 :(得分:12)

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

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

Why does Django create migration files for proxy models?

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

答案 3 :(得分:8)

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

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

答案 4 :(得分:4)

在今天下午的大部分时间里都试图自己解决这个错误,经历了各种可能混合的评论应用程序&#39;删除表格&#39;并删除整个数据库我发现我的问题是由于简单缺乏“迁移”而造成的。文件夹和所述文件夹中的__ init__.py文件。

其中一个较正确的答案现在已不再正确,因为它们修复了here提到的问题。

检查包含&quot; init.py&#39;中提到的模型的每个目录。它应该消失。

可能不会解决所有人的问题,但这有助于我的。

答案 5 :(得分:3)

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

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

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

另一个建议是:直接转到django代码并检查导致“基础”问题的原因。转到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,))

答案 6 :(得分:2)

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

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

我重命名了一堆代理模型的父表之后出现了这个问题。我通过以下方式解决了这个问题:

  1. 删除父表名称更改的迁移文件。
  2. 使用postgres终端,我将父表重命名为其先前的名称。
  3. 再次启用makemigrationsmigrate

答案 9 :(得分:0)

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

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

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

答案 12 :(得分:0)

如果您在已经有一个迁移文件夹(其中有一个 init .py文件)的应用中发生这种情况,请删除所有其他文件,然后运行makemigrations和{{ 1}}。

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

答案 13 :(得分:0)

以防万一有人犯了与我相同的错误,我也遇到了同样的问题,因为我没有对Proxy模型进行任何迁移。对我而言,这似乎没有必要,因为他们没有自己的数据库表,并且在文档中我也没有看到任何提及此内容的信息。 python manage.py makemigrations <APP_NAME>马上将其修复。

答案 14 :(得分:0)

有一个相关的问题。在此处查看我的回答 https://stackoverflow.com/a/67500550/502045

TL;博士

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

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