使用Django User模型遇TypeError:传入4个参数却被识别为5个
问题分析与解决方案
嘿,这个问题我之前也踩过坑,核心是你对Django 1.11中User.objects.create_user()的参数结构理解错啦!
为什么会报错?
先来看看Django 1.11里这个方法的定义签名:
def create_user(self, username, email=None, password=None, **extra_fields):
它只接受最多3个额外的位置参数(加上自身的self总共4个),但你现在直接把first_name、last_name、email、password这4个值按位置传进去,相当于给函数递了4个位置参数,加上管理器实例的self就变成了5个,完全超出了方法的参数限制,所以才会抛出那个TypeError。
而且更关键的是:create_user()的第一个必填位置参数是username,你现在把first_name放在了这个位置,这完全不符合方法的设计预期。
怎么修复?
根据你的业务需求,有两种常见的修复方式:
方式一:用邮箱作为用户名(很多网站都用这种方案)
如果你的系统不需要单独的用户名,直接用邮箱来标识用户,那可以把邮箱同时传给username和email参数,剩下的字段用关键字参数传递:
def register(request): if request.method == "GET": form = UserForm() return render(request, '你的注册模板路径.html', {'form': form}) # 补上GET请求的模板返回 if request.method == "POST": form = UserForm(request.POST) if form.is_valid(): user = User.objects.create_user( username=form.cleaned_data['email'], # 把邮箱作为username email=form.cleaned_data['email'], password=form.cleaned_data['password'], first_name=form.cleaned_data['first_name'], last_name=form.cleaned_data['last_name'] ) return redirect('article:index') # 加return,用url名称而非模板路径 # 表单验证失败时返回表单页面 return render(request, '你的注册模板路径.html', {'form': form})
方式二:添加独立的用户名字段
如果你的系统需要单独的用户名,那得先修改表单,添加username字段:
# forms.py class UserForm(forms.ModelForm): # 给密码字段加上密码输入框,避免明文输入 password = forms.CharField(widget=forms.PasswordInput) class Meta: model = User fields = ['username', 'first_name', 'last_name', "email", "password"]
然后在视图里正确传递参数:
def register(request): if request.method == "GET": form = UserForm() return render(request, '你的注册模板路径.html', {'form': form}) if request.method == "POST": form = UserForm(request.POST) if form.is_valid(): user = User.objects.create_user( form.cleaned_data['username'], # 第一个参数是必填的username form.cleaned_data['email'], # 第二个是可选的email form.cleaned_data['password'], # 第三个是可选的password # 额外字段用关键字参数传递 first_name=form.cleaned_data['first_name'], last_name=form.cleaned_data['last_name'] ) return redirect('article:index') return render(request, '你的注册模板路径.html', {'form': form})
额外的小提醒
- 你的原视图里漏了GET请求时的模板返回,而且POST分支的
redirect没有加return,这会导致视图没有合法返回值,后续可能触发其他错误。 - 表单里的密码字段建议加上
PasswordInput组件,这样用户输入密码时会显示为圆点,更符合安全习惯。
内容的提问来源于stack exchange,提问作者Wizard
相关产品推荐
相关产品推荐

