I would like to add a custom manager to the built-in auth.User
model.
I avoid switching to my own user model because of existing data in the database linking to the auth_user table.
So I add the following to models.py:
from django.contrib.auth.models import User, UserManager
class ActiveUserManager(UserManager):
use_in_migrations = False
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
# Monkeypatch auth.User to have custom manager
User.add_to_class('active_users', ActiveUserManager())
This seems to work, until when I run python manage.py makemigrations
, Django creates a migration file 000n_auto_20181002_1721.py
in myvenv/Lib/site-packages/django/contrib/auth/migrations
folder, with the following content:
# imports omitted
class Migration(migrations.Migration):
dependencies = [
('auth', '0008_alter_user_username_max_length'),
]
operations = [
migrations.AlterModelManagers(
name='user',
managers=[
('active_users', django.db.models.manager.Manager()),
('objects', django.contrib.auth.models.UserManager()),
],
),
]
Setting use_in_migrations = False
in class ActiveUserManager
does not help.
I would appreciate your suggestions on how to avoid creating this migration file or how to add a custom manager to the built-in auth.User
model without this behavior. I am using Django 1.11.
You can selectively disable migration for one or more Django-Models by setting managed = False in Django Model Meta options.
1. Run makemigrations to verify if your schema and your database are identical, but if our local initial migration is differs from the one that was applied to the database , Django won't let us know of this, and it'll say that is all good, but because of that, the local differences that you have won't be applied. 2.
There is only one file in migration folder that you should not ignore. That file is init.py file, If you ignore it, python will no longer look for submodules inside the directory, so any attempts to import the modules will fail.
makemigrations is responsible for packaging up your model changes into individual migration files - analogous to commits - and migrate is responsible for applying those to your database.
Figured it out.
I needed to also add 'objects'
manager to User
class, otherwise Django treats 'active_users'
as the default manager.
Full code below:
from django.contrib.auth.models import User, UserManager
class ActiveUserManager(UserManager):
use_in_migrations = False
def get_queryset(self):
return super().get_queryset().filter(is_active=True)
# IMPORTANT! to add 'objects' manager
# Otherwise Django treats 'active_users' as the default manager
User.add_to_class('objects', UserManager())
# Monkeypatch auth.User to have custom manager
User.add_to_class('active_users', ActiveUserManager())
I realized this by reading ModelState.fromModel(), where 'active_users'
was _default_manager
when 'objects'
manager was not set by User.add_to_class('objects', UserManager())
.
Default manager gets added to migration even when use_in_migrations = False
is set.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With