如何解决django CustomUser在迁移中的双重行为问题?

时间:2019-10-09 11:17:19

标签: django migration data-migration migrate django-custom-user

我有如下数据迁移,其中我想使用CustomUser的create_user方法,获取创建的用户的实例,并使用该实例创建Partner模型的实例。 值得一提的是,我拥有一个与CustomUser一对一关系的合作伙伴模型。  我有两个选择:

# 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(...),则无法在此处设置密码。

1 个答案:

答案 0 :(得分:0)

Django仅保留有关每个模型版本的有限历史信息。自here以来,它无法跟踪的一件事就是自定义模型管理器。

好消息是there's a way强制迁移系统使用您的自定义管理器:

  

您可以选择将管理器序列化为迁移,并使其在RunPython操作中可用。这是通过在管理器类上定义use_in_migrations属性来完成的。

如上所述,这仅允许您的迁移使用运行迁移时存在的管理器版本;因此,如果您以后对其进行更改,则可能会中断迁移。一种更安全的选择是只将相关的create_user代码复制到迁移本身中。