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

Django创建User时同步生成关联UserProfile报错的解决方法

解决Django创建User时同步生成UserProfile的报错问题

场景说明

在core应用中自定义了继承AbstractUser的User模型,已在settings.py中配置AUTH_USER_MODEL = 'core.User',同时定义了与User一对一关联的UserProfile模型,需求是创建新User时自动生成对应的UserProfile。

模型代码如下:

# file name: core/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser


class User(AbstractUser):
    email = models.EmailField(unique=True)
    

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)

问题现象

使用shell创建用户时触发报错:

>>> bob = User.objects.create_user(email="bob@outlook.com", username="bob")

TypeError: int() argument must be a string, a bytes-like object or a real number, not 'ModelBase'
The above exception was the direct cause of the following exception:

TypeError: Field 'id' expected a number but got <class 'core.models.User'>.

During handling of the above exception, another exception occurred:

ValueError: Cannot assign "<class 'core.models.User'>": "UserProfile.user" must be a "User" instance.

错误原因

信号处理函数中误用了sender参数:post_save信号的sender是模型类(如User类),而非创建出的用户实例。之前的代码把模型类传给UserProfile.user字段,导致类型不匹配,触发报错。

此外,原代码的异常处理逻辑冗余,且手动赋值sender.userprofile完全没必要,一对一关联会自动生成反向属性。

修正方案

修改signals.py代码,从kwargs中获取实际的用户实例instance,并通过created参数判断是否为新建用户:

# file name: core/signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver
from core.models import User, UserProfile

@receiver(post_save, sender=User)
def create_userprofile(sender, instance, created, **kwargs):
    # 仅当用户是新建时创建对应的UserProfile
    if created:
        UserProfile.objects.create(user=instance)

说明

修改后,调用User.objects.create_user创建新用户时:

  1. post_save信号会在用户保存成功后触发
  2. created参数为True,会自动创建关联的UserProfile
  3. 使用的是实际的用户实例instance,不会再出现类型不匹配的错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 20:47:29