Reputation: 8187
I'm testing a django migration inspired by this article. This method/ the MigrationTestCase
works fine outside the user model, but seems to fall down when trying to access my custom user model.
Here is the test method:
from kapsule.tests.test_migrations import MigrationTestCase
from django.db import connection
from django.db.migrations.executor import MigrationExecutor
from django.test.testcases import TransactionTestCase
class MigrationTestCase(TransactionTestCase):
"""
A Test case for testing migrations
"""
# These must be defined by subclasses.
migrate_from = None
migrate_to = None
def setUp(self):
super(MigrationTestCase, self).setUp()
self.executor = MigrationExecutor(connection)
self.executor.migrate(self.migrate_from)
def migrate_to_dest(self):
self.executor.loader.build_graph() # reload.
self.executor.migrate(self.migrate_to)
@property
def old_apps(self):
return self.executor.loader.project_state(self.migrate_from).apps
@property
def new_apps(self):
return self.executor.loader.project_state(self.migrate_to).apps
class SummaryTestCase(MigrationTestCase):
"""
Test db migration
"""
migrate_from = [('accounts', '0003_subscription')]
migrate_to = [('accounts', '0004_create_tokens')]
def setup_before_migration(self):
User = self.old_apps.get_model('accounts', 'CustomUser')
demo_user = User.objects.create_user(email='[email protected]', # nosec
password='ni likey no lightey',
first_name='Contact',
last_name='Me',
company='Group',
country='FR',
)
def test_token_populated(self):
# runs setup
self.setup_before_migration()
Here is (a truncated version of) my user model (including my custom user manager):
class CustomUserManager(BaseUserManager):
def _create_user(self, email, password, **extra_fields):
...
return user
def create_user(self, email, password, **extra_fields):
...
return self._create_user(email, password, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
...
return self._create_user(email, password, **extra_fields)
class CustomUser(AbstractUser):
"""
Replace username by email as required and unique.
"""
# Hide username
username = None
# Overidde other fields
email = models.EmailField(_('email address'), unique=True)
first_name = models.CharField(_('first name'))
...
# Override the UserManager with our custom one (for objects creation)
objects = CustomUserManager()
I see the error:
AttributeError: 'Manager' object has no attribute 'create_user'
but i don't understand why, as this is clearly defined on the model, and works correctly outside of the test case.
Any help that you can give is greatly appreciated.
EDIT:
Traceback:
======================================================================
ERROR: test_token_populated (accounts.tests.test_migrations.SummaryTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/code/accounts/tests/test_migrations.py", line 59, in test_token_populated
self.setup_before_migration()
File "/code/accounts/tests/test_migrations.py", line 43, in setup_before_migration
demo_user = User.objects.create_user(email='[email protected]', # nosec
AttributeError: 'Manager' object has no attribute 'create_user'
Upvotes: 1
Views: 1387
Reputation: 6598
You are using historical model to create user in your test case (setup_before_migration
method). Custom managers are not serialized by default to be used with historical models. Please set use_in_migrations = True
in custom user manager, delete your migrations and make them again. like this
class CustomUserManager(BaseUserManager):
use_in_migrations = True
...
You can read more about it here (historical models) and here (use_in_migrations)
Upvotes: 4