Django注册API报错:password_f字段值需为True/False/None
问题分析与解决方案
报错根源
错误提示['“test” value must be either True, False, or None.']出现在password_f字段,核心原因有两个:
- 参数传递顺序错误:你的
RegisterSerializer.create方法调用create_user时,参数顺序与自定义CustomUserManager的create_user方法不匹配,导致password_f的字符串值被传入了布尔类型的参数位(比如is_active),触发布尔值验证失败。 - 冗余且错误的密码字段:
AbstractBaseUser已经内置了加密的password字段,你自定义的password_f完全多余,且无法实现密码加密存储,同时会引发字段混淆。
分步修复
1. 修正CustomUser模型
移除冗余的password_f字段,改用内置的password字段:
class CustomUser(AbstractBaseUser): username = models.CharField(max_length=200) first_name = models.CharField(max_length=300) last_name = models.CharField(max_length=300) email = models.EmailField(max_length=255, unique=True) # 移除password_f字段 profile_pic = models.ImageField(upload_to=r'Computerizer/static/Oauth/media') sub_to_newsletter = models.BooleanField(default=True) own_pc = models.BooleanField(default=False) active = models.BooleanField(default=True, null=True) staff = models.BooleanField(default=False, null=True) admin = models.BooleanField(default=False, null=True) USERNAME_FIELD = 'email' REQUIRED_FIELDS = [] objects = CustomUserManager() # 其余方法保持不变...
2. 实现正确的CustomUserManager
如果还没定义,补充以下代码(确保密码加密逻辑正确):
from django.contrib.auth.base_user import BaseUserManager class CustomUserManager(BaseUserManager): def create_user(self, email, password=None, **extra_fields): if not email: raise ValueError('必须提供邮箱地址') email = self.normalize_email(email) user = self.model(email=email, **extra_fields) user.set_password(password) # 内置方法加密密码 user.save(using=self._db) return user def create_superuser(self, email, password=None, **extra_fields): extra_fields.setdefault('admin', True) extra_fields.setdefault('staff', True) extra_fields.setdefault('active', True) if extra_fields.get('admin') is not True: raise ValueError('超级用户必须设置admin=True') return self.create_user(email, password, **extra_fields)
3. 修正序列化器
UserSerializer(移除password_f,不返回敏感密码)
class UserSerializer(serializers.ModelSerializer): class Meta: model = CustomUser fields = ('id','username','first_name','last_name','email','sub_to_newsletter','own_pc')
RegisterSerializer(改用内置password字段,设置仅写入)
class RegisterSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True) # 密码仅用于输入,不返回 class Meta: model = CustomUser fields = ('id', 'username','first_name','last_name', 'email', 'password','sub_to_newsletter','own_pc') def create(self, validated_data): password = validated_data.pop('password') # 按正确顺序传递参数:邮箱、密码、其余字段 user = CustomUser.objects.create_user( email=validated_data['email'], password=password, **validated_data ) return user
4. 执行数据库迁移
移除字段后需要更新数据库:
python manage.py makemigrations python manage.py migrate
验证修复
重新启动服务后,发送注册请求时,密码字段将被正确加密存储,且不会再触发布尔值验证错误。
内容的提问来源于stack exchange,提问作者omar shokry
相关产品推荐
相关产品推荐

