Django Rest Framework用户注册时出现KeyError 'password'问题排查
问题排查:Django REST Framework注册接口KeyError('password')及密码不匹配提示问题
问题现象
在Postman测试user_app的注册API时触发以下错误:
KeyError at /account/register/
'password'
请求方法:POST
请求URL:http://127.0.0.1:8010/account/register/
Django版本:4.1
异常类型:KeyError
异常值:'password'
异常位置:C:...\watchmate\user_app\api\serializers.py第28行save方法中
触发视图:user_app.api.views.registration_view
测试参数:
- username: example
- email: example@xyz.com
- password: example123
- password2: example12
预期返回{'error':'password2 is not same as password!'},但实际触发KeyError。
相关代码
视图文件(user_app.api.views.py)
from rest_framework.decorators import api_view from user_app.api.serializers import RegistrationSerializer from rest_framework.response import Response @api_view(['POST',]) def registration_view(request): if request.method == 'POST': serializer = RegistrationSerializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data)
序列化器文件(watchmate\user_app\api\serializers.py)
from django.contrib.auth.models import User from rest_framework import serializers class RegistrationSerializer(serializers.Serializer): password2 = serializers.CharField(style={'input_type':'password'}, write_only=True) class Meta: model = User field = ['username', 'email', 'password', 'password2'] extra_kwargs = {'password': { 'write_only':True}} def save(self): password = self.validated_data['password'] password2 = self.validated_data['password2'] if password != password2: raise serializers.ValidationError({'error':'Password is not matching!'})
问题分析与修复
1. KeyError('password')的核心原因
序列化器Meta类中的字段定义存在拼写错误:field应该是复数形式fields。因为这个错误,DRF无法识别password字段,不会将其纳入验证流程,导致validated_data中没有password键,触发KeyError。
2. 密码不匹配提示与功能缺失问题
除了拼写错误,当前代码还有两个关键问题:
- 自定义
save方法未实现用户创建逻辑,即使密码匹配也无法生成新用户 - 密码不匹配的错误提示文本与预期不一致
完整修复后的序列化器代码
from django.contrib.auth.models import User from rest_framework import serializers class RegistrationSerializer(serializers.ModelSerializer): password2 = serializers.CharField(style={'input_type':'password'}, write_only=True) class Meta: model = User fields = ['username', 'email', 'password', 'password2'] # 修正为复数fields extra_kwargs = {'password': { 'write_only':True}} def validate(self, attrs): # 将密码校验逻辑放在DRF推荐的validate方法中 password = attrs.get('password') password2 = attrs.get('password2') if password != password2: raise serializers.ValidationError({'error':'password2 is not same as password!'}) return attrs def save(self): # 实现用户创建及密码加密逻辑 user = User( username=self.validated_data['username'], email=self.validated_data['email'] ) user.set_password(self.validated_data['password']) # 使用Django内置密码加密 user.save() return user
视图优化:补充错误响应
原视图未处理序列化器验证失败的场景,建议补充:
@api_view(['POST',]) def registration_view(request): if request.method == 'POST': serializer = RegistrationSerializer(data=request.data) data = {} if serializer.is_valid(): user = serializer.save() data['response'] = "Registration successful!" data['username'] = user.username data['email'] = user.email else: data = serializer.errors # 返回验证错误信息 return Response(data)
修复后效果
当password与password2不匹配时,Postman会返回预期的错误:
{"error":"password2 is not same as password!"}
KeyError问题完全解决,密码匹配时会成功创建用户并返回注册成功信息。
内容的提问来源于stack exchange,提问作者Swati Mishra
相关产品推荐
相关产品推荐

