Django开发REST API报错create_user缺少必填位置参数username
问题原因
报错触发的核心是自定义用户模型配置和Django默认认证规则不匹配:
- Django默认用户体系将
username作为唯一身份标识,内置的用户创建逻辑默认强制要求传入username参数 - 你虽然自定义了
UserProfileManager.create_user()方法,将入参改为email、name、password,但没有在模型层完成认证标识的替换配置,框架在执行参数校验时仍按默认规则检查username字段,发现缺失就抛出该错误。
通常是漏了两个关键配置:
- 没有在自定义User模型中指定
USERNAME_FIELD = 'email',告知框架用邮箱替代用户名作为登录标识 - 没有将自定义的管理器类绑定到User模型的
objects属性,或者没有在settings中声明使用自定义用户模型。
修复方案
按以下步骤调整代码即可:
1. 完善models.py的用户模型定义
推荐继承AbstractBaseUser和PermissionsMixin实现完全自定义的用户模型,替换默认的username字段逻辑,示例代码如下:
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, PermissionsMixin from django.db import models class UserProfileManager(BaseUserManager): def create_user(self, email, name, password=None): """Create a new regular user""" if not email: raise ValueError('User must provide a valid email address') email = self.normalize_email(email) user = self.model(email=email, name=name) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, name, password): """Create a new superuser for admin access""" user = self.create_user(email=email, name=name, password=password) user.is_staff = True user.is_superuser = True user.save(using=self._db) return user class UserProfile(AbstractBaseUser, PermissionsMixin): email = models.EmailField(max_length=255, unique=True) name = models.CharField(max_length=255) is_active = models.BooleanField(default=True) is_staff = models.BooleanField(default=False) # 绑定自定义用户管理器 objects = UserProfileManager() # 核心配置:用email替换默认username作为登录标识 USERNAME_FIELD = 'email' # 创建用户时除邮箱、密码外的必填字段 REQUIRED_FIELDS = ['name'] def __str__(self): return self.email
如果之前已经执行过数据库迁移,修改用户模型后需要清空原有迁移文件和数据库,重新执行
makemigrations和migrate命令,否则会出现字段冲突报错。
2. 在settings.py中声明自定义用户模型
找到项目的settings.py文件,添加如下配置,替换Django默认的User模型:
# 格式为 "你的app名.模型类名" AUTH_USER_MODEL = 'profiles.UserProfile'
3. 优化serializers.py逻辑
你当前写的create方法逻辑本身没有问题,只需要补充密码字段的仅写配置,避免接口返回密码哈希值即可:
from rest_framework import serializers from . import models class UserProfileSerializer(serializers.ModelSerializer): class Meta: model = models.UserProfile fields = ('id', 'email', 'name', 'password') extra_kwargs = { 'password': { 'write_only': True, 'style': {'input_type': 'password'} } } def create(self, validated_data): user = models.UserProfile.objects.create_user( email=validated_data['email'], name=validated_data['name'], password=validated_data['password'] ) return user
修改完成后重启服务,再调用用户创建接口就不会再出现缺少username参数的报错。
内容的提问来源于stack exchange,提问作者Azpect
相关产品推荐
相关产品推荐

