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

Django自定义用户模型存表单数据报错:User()收到意外关键字参数

问题原因

你遇到的错误是因为自定义User模型中没有speciality、department这些字段,但你把表单里所有字段(包括学生专属字段)都传给了User.objects.create_user()方法,导致User模型无法识别这些额外参数。

由于你设计了Student和Teacher两种用户类型,正确的做法是:基础User模型只保存通用字段(用户名、邮箱、密码等),学生专属字段(speciality、department等)应该放在单独的Student模型中,通过一对一关联和User绑定。

解决步骤

1. 确认模型结构(示例)

假设你的自定义User模型和Student模型如下(如果还没定义,先补上):

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

# 基础自定义用户模型,只存储通用字段
class User(AbstractUser):
    pass

# 学生专属模型,与User一对一关联
class Student(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='student_profile')
    nation = models.CharField(choices=NATIONALITY_CHOICES, blank=True, max_length=50)
    sex = models.CharField(choices=SEX_CHOICES, blank=True, max_length=10)
    phone = models.CharField(max_length=50)
    address = models.CharField(max_length=50)
    department = models.CharField(choices=DEPARTMENT_CHOICES, blank=True, max_length=50)
    speciality = models.CharField(choices=SPECIALITY_CHOICES, blank=True, max_length=50)
    shift = models.CharField(choices=SHIFT_CHOICES, blank=True, max_length=20)
    plan = models.CharField(choices=TYPE_CHOICES, blank=True, max_length=20)
    medical_notes = models.TextField(blank=True)
    campus = models.CharField(choices=CAMPUS_CHOICES, blank=True, max_length=50)

2. 修改表单的save方法

把表单数据拆分成User字段和Student字段,分别创建User和Student实例:

def save(self):
    """Create user and student profile."""
    data = self.cleaned_data
    data.pop("password_confirmation")  # 移除确认密码字段

    # 拆分User模型需要的字段和Student专属字段
    user_field_names = ['username', 'email', 'first_name', 'last_name', 'password']
    user_data = {key: value for key, value in data.items() if key in user_field_names}
    student_data = {key: value for key, value in data.items() if key not in user_field_names}

    # 创建User(create_user会自动加密密码)
    user = User.objects.create_user(**user_data)
    # 创建Student并关联到刚创建的User
    Student.objects.create(user=user, **student_data)
    
    return user

3. 表单小修复

你的medical_notes字段定义有误,forms.Textarea是组件而非字段类型,应该改成:

medical_notes = forms.CharField(
    widget=forms.Textarea(attrs={"class": "form-control", "placeholder": "Medical notes"}),
    required=False
)

另外,clean方法可以优化避免KeyError:

def clean(self):
    """Verify password confirmation match."""
    data = super().clean()
    password = data.get("password")
    password_confirmation = data.get("password_confirmation")

    if password and password_confirmation and password != password_confirmation:
        raise forms.ValidationError("Passwords do not match.")

    return data

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:22:49