Django REST API用户注册密码未正确保存 Admin显示无效密码格式
问题根因定位
你遇到的密码存储异常,核心是代码缩进错误导致自定义的密码加密逻辑完全未生效。
原代码中create方法被错误缩进到Meta类内部,没有作为RegisterSerializer的类方法存在。DRF的ModelSerializer在执行保存逻辑时,识别不到这个自定义的create方法,会走默认的字段直连保存逻辑——直接把请求传过来的明文密码赋值给User实例的password字段后入库,没有经过Django内置的密码哈希流程,最终存储的密码格式不符合Django要求,才会在Admin页弹出「Invalid password format or unknown hashing algorithm.」的提示。
修正方案
- 调整代码缩进,将
create方法移出Meta类作用域,确保它和Meta类在RegisterSerializer中是平级关系,能被DRF正常识别调用 - 补充邮箱字段的赋值逻辑,避免注册时传入的邮箱值无法正常存入数据库
- 已经存在的明文密码用户,需要通过Django自带的密码哈希逻辑做批量修正,否则旧数据依然会触发密码格式错误提示
修正后完整代码
serializers.py
from rest_framework import serializers from django.contrib.auth.models import User class RegisterSerializer(serializers.ModelSerializer): class Meta: model = User fields = ('id', 'username', 'email', 'password') extra_kwargs = {'password': {'write_only': True}} # 调整缩进:与Meta类平级,为序列化器的自定义创建方法 def create(self, validated_data): user = User( username=validated_data['username'], email=validated_data.get('email', '') ) # 调用Django内置的密码哈希方法存储密码 user.set_password(validated_data['password']) user.save() return user
views.py
当前视图层逻辑无错误,可保持原有实现,示例参考:
from rest_framework import generics from rest_framework.permissions import AllowAny from rest_framework.response import Response from rest_framework.authtoken.models import Token from .serializers import RegisterSerializer class CreateUser(generics.CreateAPIView): permission_classes = [AllowAny] serializer_class = RegisterSerializer def post(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) user = serializer.save() token, _ = Token.objects.get_or_create(user=user) return Response({ "user": RegisterSerializer(user, context=self.get_serializer_context()).data, "token": token.key })
注意:修正代码后新注册的用户会自动按正确的密码格式存储,历史遗留的明文密码数据需要单独做哈希更新,否则旧用户的密码登录、密码校验流程都会失效。
内容的提问来源于stack exchange,提问作者kokiwebaaa
相关产品推荐
相关产品推荐

