如何解决django CustomUser在迁移中的Dual behavior问题?
How to solve the problem of Dual behavior of django CustomUser in migration?
我有如下数据迁移,其中我想使用 CustomUser 的 create_user 方法,获取已创建用户的实例,并使用此实例创建合作伙伴模型的实例。
值得一提的是,我有一个与 CustomUser 具有一对一关系的 Partner 模型。
我有两个选择:
# Option One:
def populate_database_create_partner(apps, schema_editor):
Partner = apps.get_model('partners', 'Partner')
CustomUser.objects.create_user(
id=33,
email='test_email@email.com',
password='password',
first_name='test_first_name',
last_name="test_last_name",
is_partner=True,
)
u = CustomUser.objects.get(id=33)
partner = Partner.objects.create(user=u, )
class Migration(migrations.Migration):
dependencies = [
('accounts', '0006_populate_database_createsuperuser'),
]
operations = [
migrations.RunPython(populate_database_create_partner),
]
在选项一中,我看到了这个错误:
ValueError: Cannot assign "<CustomUser: test_email@email.com>": "Partner.user" must be a "CustomUser" instance.
然后我测试这个:
# Option Two:
def populate_database_create_partner(apps, schema_editor):
Partner = apps.get_model('partners', 'Partner')
CustomUser = apps.get_model('accounts', 'CustomUser')
CustomUser.objects.create_user(
id=33,
email='test_email@email.com',
password='password',
first_name='test_first_name',
last_name="test_last_name",
is_partner=True,
)
u = CustomUser.objects.get(id=33)
partner = Partner.objects.create(user=u, )
class Migration(migrations.Migration):
dependencies = [
('accounts', '0006_populate_database_createsuperuser'),
]
operations = [
migrations.RunPython(populate_database_create_partner),
]
我看到这个错误:
CustomUser.objects.create_user(
AttributeError: 'Manager' object has no attribute 'create_user'
create_user方法无效。
如果我不使用create_user方法而只使用CustomUser.objects.create(...)
,我将无法在这里设置密码。
Django 仅保留有关每个模型版本的有限历史信息。如记录 here 所述,它没有跟踪的事情之一是自定义模型管理器。
好消息是 there's a way 强制迁移系统使用您的自定义管理器:
You can optionally serialize managers into migrations and have them available in RunPython
operations. This is done by defining a use_in_migrations
attribute on the manager class.
如前所述,这仅允许您的迁移使用迁移 运行 时存在的管理器版本;因此,如果您稍后对其进行更改,则可能会中断迁移。更安全的替代方法是将相关的 create_user
代码复制到迁移本身中。
我有如下数据迁移,其中我想使用 CustomUser 的 create_user 方法,获取已创建用户的实例,并使用此实例创建合作伙伴模型的实例。 值得一提的是,我有一个与 CustomUser 具有一对一关系的 Partner 模型。 我有两个选择:
# Option One:
def populate_database_create_partner(apps, schema_editor):
Partner = apps.get_model('partners', 'Partner')
CustomUser.objects.create_user(
id=33,
email='test_email@email.com',
password='password',
first_name='test_first_name',
last_name="test_last_name",
is_partner=True,
)
u = CustomUser.objects.get(id=33)
partner = Partner.objects.create(user=u, )
class Migration(migrations.Migration):
dependencies = [
('accounts', '0006_populate_database_createsuperuser'),
]
operations = [
migrations.RunPython(populate_database_create_partner),
]
在选项一中,我看到了这个错误:
ValueError: Cannot assign "<CustomUser: test_email@email.com>": "Partner.user" must be a "CustomUser" instance.
然后我测试这个:
# Option Two:
def populate_database_create_partner(apps, schema_editor):
Partner = apps.get_model('partners', 'Partner')
CustomUser = apps.get_model('accounts', 'CustomUser')
CustomUser.objects.create_user(
id=33,
email='test_email@email.com',
password='password',
first_name='test_first_name',
last_name="test_last_name",
is_partner=True,
)
u = CustomUser.objects.get(id=33)
partner = Partner.objects.create(user=u, )
class Migration(migrations.Migration):
dependencies = [
('accounts', '0006_populate_database_createsuperuser'),
]
operations = [
migrations.RunPython(populate_database_create_partner),
]
我看到这个错误:
CustomUser.objects.create_user(
AttributeError: 'Manager' object has no attribute 'create_user'
create_user方法无效。
如果我不使用create_user方法而只使用CustomUser.objects.create(...)
,我将无法在这里设置密码。
Django 仅保留有关每个模型版本的有限历史信息。如记录 here 所述,它没有跟踪的事情之一是自定义模型管理器。
好消息是 there's a way 强制迁移系统使用您的自定义管理器:
You can optionally serialize managers into migrations and have them available in
RunPython
operations. This is done by defining ause_in_migrations
attribute on the manager class.
如前所述,这仅允许您的迁移使用迁移 运行 时存在的管理器版本;因此,如果您稍后对其进行更改,则可能会中断迁移。更安全的替代方法是将相关的 create_user
代码复制到迁移本身中。