[Django]-Django Migrations ValueError: Could not find manager in django.db.models.manager

3👍

Turns out, since Django 1.8 we can serialize Managers using use_in_migrations.

And the CurrentSiteManager is marked with use_in_migrations = True

So the fix is to set back use_in_migrations = False. I did it this way:

class NewsSiteManager(CurrentSiteManager.from_queryset(NewsQuerySet)):
    use_in_migrations = False


class News(models.Model):
    #...

    objects = NewsQuerySet.as_manager()
    on_site = NewsSiteManager()
👤Todor

3👍

There’s a better way to do this.

from django.db import models

class NewsManager(models.Manager.from_queryset(NewsQuerySet)):
    use_in_migrations = True


class News(models.Model):
    ...

    objects = NewsManager()

Then you can do whatever additional things you want with CurrentSiteManager objects.

1👍

The accepted answer works, but it’s not so great if you actually want to keep the managers serialised as part of the migrations (so you can use them!).

To do that, you need to follow what the error message says and inherit from the generated manager, and then use your subclass:

from django.contrib.sites.managers import CurrentSiteManager as DjangoCurrentSiteManager

class NewsQuerySet(models.QuerySet):
    pass

class CurrentSiteManager(DjangoCurrentSiteManager.from_queryset(NewsQuerySet)):
    pass

class News(models.Model):
     # Fields...

    objects = NewsQuerySet.as_manager()
    on_site = CurrentSiteManager()

0👍

If you are using mypy the accepted solution will result in the following typing error:

Unsupported dynamic base class "CurrentSiteManager.from_queryset"

I noticed that what Django is really looking for here is an importable path to your custom manager, which it reads from the class __module__ and __name__ dunder attributes.

When you create a custom manager class with BaseManager.from_queryset these attributes point to a dynamic class name in the django.db.models.manager module, which is not importable. You can fix it by assigning them to the appropriate location to your custom manager class:

NewsSiteManager = CurrentSiteManager.from_queryset(NewsQuerySet)()
NewsSiteManager.__module__ = __name__
NewsSiteManager.__name__ = "NewsSiteManager"

The resulting migration operation will then look something like this:

migrations.AlterModelManagers(
    name="news",
    managers=[
        ("objects", news.models.NewsSiteManager()),
    ],
)

It looks a bit ugly at first but it’s actually more correct than the values that these variables have by default.

Leave a comment