django 迁移测试:'Manager' object has no attribute 错误
django migrations test: 'Manager' object has no attribute error
我正在测试受 this article 启发的 django 迁移。此方法/ MigrationTestCase
在用户模型之外工作正常,但在尝试访问我的自定义用户模型时似乎失败了。
测试方法如下:
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='contact@me.fr', # 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()
这是我的用户模型(包括我的自定义用户管理器)的(截断版本):
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()
我看到错误:
AttributeError: 'Manager' object has no attribute 'create_user'
但我不明白为什么,因为这在模型上有明确定义,并且在测试用例之外也能正常工作。
非常感谢您提供的任何帮助。
编辑:
回溯:
======================================================================
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='contact@me.fr', # nosec
AttributeError: 'Manager' object has no attribute 'create_user'
您正在使用历史模型在测试用例中创建用户(setup_before_migration
方法)。默认情况下,自定义管理器不会序列化以与历史模型一起使用。请在自定义用户管理器中设置 use_in_migrations = True
,删除您的迁移并重新进行。像这样
class CustomUserManager(BaseUserManager):
use_in_migrations = True
...
您可以阅读更多相关信息here (historical models) and here (use_in_migrations)
我正在测试受 this article 启发的 django 迁移。此方法/ MigrationTestCase
在用户模型之外工作正常,但在尝试访问我的自定义用户模型时似乎失败了。
测试方法如下:
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='contact@me.fr', # 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()
这是我的用户模型(包括我的自定义用户管理器)的(截断版本):
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()
我看到错误:
AttributeError: 'Manager' object has no attribute 'create_user'
但我不明白为什么,因为这在模型上有明确定义,并且在测试用例之外也能正常工作。
非常感谢您提供的任何帮助。
编辑:
回溯:
======================================================================
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='contact@me.fr', # nosec
AttributeError: 'Manager' object has no attribute 'create_user'
您正在使用历史模型在测试用例中创建用户(setup_before_migration
方法)。默认情况下,自定义管理器不会序列化以与历史模型一起使用。请在自定义用户管理器中设置 use_in_migrations = True
,删除您的迁移并重新进行。像这样
class CustomUserManager(BaseUserManager):
use_in_migrations = True
...
您可以阅读更多相关信息here (historical models) and here (use_in_migrations)