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

Django数据迁移分配用户报错:无法赋值User实例给Client.primary_contact

解决Django迁移中Cannot assign "User": "Client.primary_contact" must be a "User" instance错误

问题重现

执行pytest初始化时,数据迁移抛出如下错误:

ValueError: Cannot assign "<User: redshred_default_contact>": "Client.primary_contact" must be a "User" instance.

调试时确认isinstance(default_user, User)和isinstance(default_user, get_user_model())均返回True,但外键赋值仍失败。

问题原因

Django迁移运行时使用的是历史模型版本——这些模型是从迁移依赖中动态构建的,和你直接从django.contrib.auth.models导入的当前模型类不是同一个Python对象。

你的迁移代码里,Client模型通过apps.get_model获取(符合迁移规范),但User和Group却直接用了导入的类创建实例。两者的模型类版本不匹配,导致外键字段进行类型校验时失败。

解决方案

修改迁移函数,所有模型类统一通过apps.get_model获取,确保使用同一版本的模型类:

# Generated by Django 4.2.4 on 2023-09-14 18:13

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

def assign_default_client(apps, schema_editor):
    Client = apps.get_model("apiserver_v2", "Client")
    # 从配置中解析用户模型的app和名称,兼容自定义用户模型
    user_app, user_model = settings.AUTH_USER_MODEL.split('.')
    User = apps.get_model(user_app, user_model)
    client = Client.objects.get(slug="default-client")
    User.objects.update(account__client=client)

def create_default_client(apps, schema_editor):
    # 通过apps获取用户模型
    user_app, user_model = settings.AUTH_USER_MODEL.split('.')
    User = apps.get_model(user_app, user_model)
    (default_user, _) = User.objects.get_or_create(username="default_contact")
    default_user.save()
    Client = apps.get_model("apiserver_v2", "Client")

    client = Client.objects.create(
        name="Default Client",
        slug="default-client",
        primary_contact=default_user,
        domain="mydomain.com",
    )

    # 通过apps获取Group模型
    Group = apps.get_model('auth', 'Group')
    (group, _) = Group.objects.get_or_create(name="default_contact_group")
    client.new_user_group = group
    client.save()

class Migration(migrations.Migration):
    dependencies = [
        ("apiserver_v2", "0026_account"),
        ("authtoken", "0003_tokenproxy"),
    ]

    operations = [
        migrations.RunPython(create_default_client, migrations.RunPython.noop),
        migrations.RunPython(assign_default_client, migrations.RunPython.noop),
    ]

关键注意事项

  1. 用户模型处理:通过settings.AUTH_USER_MODEL拆分获取app和模型名,兼容默认auth.User和自定义用户模型场景,避免硬编码。
  2. 所有模型统一:迁移中永远不要直接导入模型类,必须使用apps.get_model,否则会出现跨版本模型实例不兼容的问题。
  3. Group模型同步:Group同样需要通过apps.get_model获取,保持迁移内模型类的一致性。

内容的提问来源于stack exchange,提问作者Skaman Sam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:04:56