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

18

40

When I run tests I get this error during database initialization:

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)

I created this proxy for contrib.auth Group model to place it in my app in django admin:

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

So what can I do to fix this issue?

Tented answered 15/5, 2015 at 19:21 Comment(3)
@Dimitry Mikhaylov did you solve this issue ? I'm also facing the exact same error for the proxy I've set. I'd be glad if you can help me.Lyonnesse
I had to run migrations for contrib.auth before, it didn't work otherwise.Tented
You may need to create a migrations folder with an empty init.py in it so Django can actually create the migration file. See the answer by Tamriel #27261530Averroes
A
32

After a lot of digging on this the only thing that worked for me was

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

Just a workaround but hopefully it helps somebody.

Attach answered 30/7, 2015 at 20:22 Comment(2)
just add a folder named "migrations" and in it create "init.py" file.Drakensberg
do u mean commenting them out from INSTALLED_APPS?Lucero
B
34

Simply creating a migrations directory at the root of your app (so users/migrations/ in your case) and adding an empty __init__.py file might resolve your issue. At least it did for me when I was getting the same error.

But you're better off running makemigrations for your app, as suggested by @zenofewords above. That will create the directory for you AND generate migrations for your proxy models.

Why does Django create migration files for proxy models?

Your tests are looking for those migrations and aren't finding them.

Boat answered 11/1, 2017 at 17:21 Comment(1)
I think this should be the accepted answer in my opinion.Christelchristen
A
32

After a lot of digging on this the only thing that worked for me was

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

Just a workaround but hopefully it helps somebody.

Attach answered 30/7, 2015 at 20:22 Comment(2)
just add a folder named "migrations" and in it create "init.py" file.Drakensberg
do u mean commenting them out from INSTALLED_APPS?Lucero
C
24

I've come across this issue, and as commenting out the model isn't really a solution, I've found that setting the undocumented auto_created = True to the Meta class will make Django ignore it.

class GroupProxy(Group):

    class Meta:
        proxy = True
        auto_created = True
Cinquefoil answered 20/5, 2016 at 13:39 Comment(1)
This will cause problems when creating the permissions for those apps though, so use it with careMagner
C
15

Have you tried running manage.py makemigrations <app_label> on your app before running tests?

Also, check if the app which model(s) you are trying to Proxy is included in your INSTALLED_APPS.

Converted answered 26/5, 2015 at 9:44 Comment(2)
when you run python manage.py test it will try to create test DB and apply all migrations before running tests.Tented
I already had a database, but was missing the migrations files. After I did this (makemigrations <app>), I got errors that the app_name.model_name table already exists I solved this by editing the migration file (app/migrations/0001_initial.py) and commenting out every line in the operations = [...] list.Moonstone
S
7

add a folder named "migrations" and in this folder create "__init__.py" file

Sherwin answered 5/6, 2020 at 5:7 Comment(0)
N
6

Having spent the majority of this afternoon trying to solve this error myself, going through every conceivable mixture of 'commenting out apps', 'dropping tables' and dropping entire databases I found that my issue was caused by a simple lack of a 'migrations' folder and an __ init__.py file inside of said folder.

One of the older answers which was correct is now no longer correct as they have fixed the issue mentioned here.

Check every directory that contains the model mentioned in 'init.py' and it should go away.

Probably won't solve everyone's case but it helped mine.

Neustria answered 21/11, 2017 at 17:26 Comment(1)
run makemigrations for all the apps that you are using.Lucero
A
5

I also faced this issue (after doing some complex model inheritance). One of my migrations contained

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

I deleted shop.Entity model entirely, but the migration was referencing it in bases attribute. So I just deleted bases=('shop.entity',) and it works. It will probably break an opportunity to migrate from the beginning, but at least allows to migrate further on.

Another advice would be: go directly to django code and inspect what's causing "bases" trouble. Go to django/db/migrations/state.py and add a breakpoint:

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,))
Acord answered 29/10, 2017 at 8:30 Comment(0)
H
3

I had this problem after I renamed the parent table of a bunch of my proxy models. I resolved it by:

  1. Deleting the migration file that had the name change for the parent table.
  2. Using the postgres terminal, I renamed the parent table to its previous name.
  3. Ran makemigrations and migrate again
Heliozoan answered 24/8, 2016 at 16:6 Comment(0)
E
0

If this is only happening when running python manage.py test (maybe because you have already made the necessary migrations), you should explicitly say that contrib.auth should not migrate in the MIGRATION_MODULES of your settings module.

MIGRATION_MODULES(
        'auth': "contrib.auth.migrations_not_used_in_tests",
)
Edgaredgard answered 2/3, 2016 at 16:43 Comment(0)
T
0

One possibility is that the deleting or creating of a model in the migration file is in the wrong order. I experienced this in Django 1.7.8 when the base model was BEFORE the derived model. Swapping the order for deleting the model fixed the issue.

Toein answered 7/9, 2018 at 16:0 Comment(0)
I
0

happened to me with no other app - just because I renamed a model which was a base for other models (and maybe created that sub-models within the same migration) renaming the super-model to it's original name solved it for me

Ideologist answered 30/9, 2019 at 10:50 Comment(0)
S
0

I faced the same issue and adding app_label attribute in class Meta: solved the error :

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
Scheers answered 17/12, 2019 at 16:15 Comment(0)
F
0

If this occurs to you in an app that already has a migrations folder (and a init.py file in it), delete all other files, and run makemigrations and migrate again.

P.S.: You may need to reconfigure your models.py or some tables in your database manually.

Footnote answered 9/4, 2020 at 17:46 Comment(0)
S
0

Just incase anyone made the same mistake as me, I had the same issue because I hadn't made any migrations for the Proxy models. It didn't seem necessary to me as they don't have their own DB tables and I didn't see anything mentioning this in the docs. python manage.py makemigrations <APP_NAME> fixed it right up.

Sentient answered 15/5, 2020 at 16:51 Comment(0)
S
0

There's a related question. See my answer here https://mcmap.net/q/393499/-django-alter-bases-in-migrations

TL;DR

Create your own operation to remove bases

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
Sinclair answered 12/5, 2021 at 9:17 Comment(0)
L
0

You may have to run makemigrations for the apps without migrations.

In my case django_quiz depends on multichoice, true_false and essay.

I had to makemigrations for each of these before I could migrate django_quiz.

Lucero answered 8/10, 2021 at 6:58 Comment(0)
E
0

I think in my case, I just deleted the parent model inherited by the child model, let us I have CustomUser model and Inherited by Employee model, Before I deleted the employee migration, I was in error same with yours, But After I deleted it worked

Elysium answered 1/5, 2023 at 9:56 Comment(0)
D
0

I struggled with this issue for proxy models as well. I had a model A and a proxy model B. For some decisions I had to refactor the name of model A to model C, then when I run the migrations nothing worked. The reason is the next:

  • When you create your migrations using manage.py makemigrations on a proxy model the migration file is something like this:
 migrations.CreateModel(
            name='BProxy',
            fields=[
            ],
            options={
                'proxy': True,
                'indexes': [],
                'constraints': [],
            },
           bases=('app_name.database_table_name_of_a',),
        ),

more on this. If you see the bases line doesn't refer to the python model but the database table, so in my case that created and issue . So the solution:

  1. Create and empty migration and delete the proxy model
operations = [
        migrations.DeleteModel(
            name='PythonProxyModelClassName',
        ),
  1. Run again python manage.py makemigrations.

This have the advantage of keeping your migrations history clean so if you are working on different environments it will be easier to maintain them.

disclaimer: I haven't manually check if the permissions model configuration gets affected by this, but after running tests with database construction it seams it doesn´t.

Dziggetai answered 26/1 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.