Django REST Framework自定义登录中check_password函数失效问题
Django REST Framework自定义登录密码校验问题修复
你的代码有两个核心问题导致check_password无法正常工作:
问题1:获取用户的方式错误
User.objects.filter(username=username)返回的是QuerySet集合对象,哪怕只有一个匹配用户,它也不是单个User实例。这会导致两个问题:
if user is None永远不会触发,因为空QuerySet不等于None- QuerySet没有
check_password方法,直接调用会报错
问题2:参数未做安全校验
直接用request.data["username"]如果请求中没有传对应字段,会抛出KeyError,导致接口崩溃。
修正后的代码
from django.contrib.auth.models import User from rest_framework.views import APIView from rest_framework.response import Response class LoginView(APIView): def post(self, request): # 用get方法安全获取参数,避免KeyError username = request.data.get("username") password = request.data.get("password") # 先校验必填参数是否存在 if not username or not password: return Response({"response": "用户名或密码不能为空"}, status=400) try: # 用get获取单个用户实例,不存在则抛出DoesNotExist异常 user = User.objects.get(username=username) except User.DoesNotExist: return Response({"response": "用户不存在"}, status=404) # 调用User实例的check_password方法校验密码 if user.check_password(password): return Response({"response": "密码正确"}) else: return Response({"response": "密码错误"}, status=400)
关键说明
check_password是Django User模型实例的内置方法,它会自动将传入的明文密码与数据库中存储的密码哈希值进行比对(Django默认不会存储明文密码)- 使用
get()方法配合异常捕获是处理单个用户查询的标准方式,比filter().first()更明确,能直接处理用户不存在的场景 - 增加参数校验可以提升接口的健壮性,避免因请求参数缺失导致的崩溃
内容的提问来源于stack exchange,提问作者Akhil
相关产品推荐
相关产品推荐

