You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django迁移生成OneToOne关联的用户及关联对象种子数据时触发ValueError

Django迁移生成OneToOne关联的用户及关联对象种子数据时触发ValueError

嘿,我一眼就看出问题出在哪了——迁移环境中模型类的实例不匹配!你在迁移里混用了两种获取User模型的方式:get_user_model()拿到的是你当前代码里的User类,而apps.get_model()拿到的是迁移历史快照里的UserProfile/BankAccount类,这俩在Django的迁移系统里是完全不同的类实例,所以即使看起来都是User对象,Django也不认,就抛出了那个ValueError。

下面是具体的修复步骤,我帮你把代码也改好了:

1. 迁移中统一用apps.get_model()获取所有模型

在迁移里,绝对不能直接用get_user_model()或者导入当前的模型类,必须通过apps.get_model()获取对应历史版本的模型。把你迁移里的User = get_user_model()替换成通用的获取方式:

from django.conf import settings
User = apps.get_model(settings.AUTH_USER_MODEL)

如果用的是Django默认的auth用户模型,也可以直接写:

User = apps.get_model("auth", "User")

2. 修复用户密码的设置方式

你现在用User.objects.create(..., password=password)是直接把明文密码存进数据库,用户根本没法登录!必须用set_password()方法来哈希密码,这一步很重要:

把创建用户的代码从:

user = User.objects.create(username=username, email=email, password=password)

改成:

# 先创建用户,不设置密码
user = User.objects.create(username=username, email=email)
# 用set_password哈希密码后保存
user.set_password(password)
user.save()

3. 确保依赖的Currencies数据已存在

你的迁移依赖0002_seed_initial_data,必须保证这个迁移里已经创建了code="USD"的Currencies条目,不然Currencies.objects.get(code="USD")会直接报错。如果之前没创建,也可以在当前迁移里做个容错处理。

修复后的完整迁移代码

from django.db import migrations
import random
from django.conf import settings

seed_data = [
    {'first_name': 'John', 'middle_name': 'Martin', 'last_name': 'Doe', 'gender': 'MALE', 'username':'john.d', 'password':'jb2025example.cz', 'email':'john.b@example.cz'},
    {'first_name': 'Alice', 'middle_name': 'B.', 'last_name': 'Smith', 'gender': 'FEMALE', 'username': 'alice.b', 'password':'alice.b@example.cz', 'email':'ab2025example.cz'},
    {'first_name': 'Bob', 'middle_name': 'C.', 'last_name': 'Johnson', 'gender': 'MALE', 'username': 'bob.c', 'password':'bob.c@example.cz', 'email':'bc2025example.cz'},
    {'first_name': 'Carol', 'middle_name': 'D.', 'last_name': 'Williams', 'gender': 'FEMALE', 'username': 'carol.d', 'password':'carol.d@example.cz', 'email':'cd2025example.cz'},
    {'first_name': 'David', 'middle_name': 'E.', 'last_name': 'Brown', 'gender': 'MALE', 'username': 'david.e', 'password':'david.e@example.cz', 'email':'de2025example.cz'},
    {'first_name': 'Eve', 'middle_name': 'F.', 'last_name': 'Jones', 'gender': 'FEMALE', 'username': 'eve.f', 'password':'eve.f@example.cz', 'email':'ef2025example.cz'},
]

class Migration(migrations.Migration):
    dependencies = [
        ('main', '0002_seed_initial_data'),
    ]

    def seed_initial_users_and_profiles(apps, schema_editor):
        # 所有模型都通过apps.get_model获取
        UserProfile = apps.get_model("main", "UserProfile")
        BankAccount = apps.get_model("main", "BankAccount")
        Currencies = apps.get_model("main", "Currencies")
        User = apps.get_model(settings.AUTH_USER_MODEL)  # 通用方式获取User模型

        # 确保USD货币已存在(做容错处理)
        try:
            currency = Currencies.objects.get(code="USD")
        except Currencies.DoesNotExist:
            # 临时创建,建议优先在0002迁移中预创建该条目
            currency = Currencies.objects.create(country="United States", code="USD", sign="$")

        for data in seed_data:
            username = data.pop('username')
            email = data.pop('email')
            password = data.pop('password')
            balance = random.randint(900, 100_000_000)

            # 正确创建用户并设置哈希密码
            user = User.objects.create(username=username, email=email)
            user.set_password(password)
            user.save()

            # 现在创建关联的UserProfile和BankAccount就不会报错了
            UserProfile.objects.create(user=user, **data)
            # BankAccount的save方法会自动生成account_id,无需手动处理
            BankAccount.objects.create(currency_code=currency, owner=user, balance=balance)

    operations = [
        migrations.RunPython(seed_initial_users_and_profiles),
    ]

额外注意点

  • 迁移系统是基于历史快照工作的,所以任何在迁移中用到的模型,都必须通过apps.get_model()获取,绝对不能直接导入当前的模型类(包括User)。
  • 如果你以后自定义了User模型,apps.get_model(settings.AUTH_USER_MODEL)这种方式依然有效,比硬编码"auth", "User"更通用。
  • 运行迁移前,最好先检查依赖的0002迁移是否真的创建了所需的Currencies数据,避免出现DoesNotExist异常。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 10:03:04