【问题标题】:How to solve the problem of Dual behavior of django CustomUser in migration?如何解决django CustomUser在迁移中的双重行为问题?
【发布时间】:2020-02-06 17:16:42
【问题描述】:

我有如下数据迁移,我想使用 CustomUser 的 create_user 方法,获取已创建用户的实例,并使用此实例创建 Partner 模型的实例。 值得一提的是,我有一个 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(...),我将无法在此处设置密码。

【问题讨论】:

  • 你也可以在第一个解决方案中尝试partner = Partner.objects.create(user_id=33, )
  • 这样说,如果我通过import来使用模型,就可以使用它的方法了。如果我通过apps.get_model导入它们,那么方法不起作用
  • 也许你是对的,尝试通过id设置用户
  • 我遇到了另一个问题。我的合作伙伴模型有一个自定义保存方法,可以创建一个 slug。由于同样的问题,没有创建蛞蝓!方法不行!!!
  • 我需要在迁移文件中复制它

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


【解决方案1】:

Django 仅保留有关模型的每个版本的有限历史信息。正如 here 所记录的那样,它没有跟踪的一件事是自定义模型管理器。

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

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

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

【讨论】:

    猜你喜欢
    • 2018-08-01
    • 2016-10-08
    • 2021-07-07
    • 1970-01-01
    • 2010-12-07
    • 2022-06-28
    • 2020-01-06
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多