Django DRF调用CodeAPIView.post缺少3个必填参数如何修复?
错误根因
- DRF的
APIView类的请求方法(post/get等)是由路由规则触发调用的,路由只会自动传入request对象以及你在URL路径中定义的捕获参数,你在CodeAPIView.post中自定义的user/user_obj/code三个参数没有任何来源,前端请求时也不会传这三个值,自然会报参数缺失错误。 - 你的业务逻辑是两次独立的前端请求:第一次请求
AuthAPIView发验证码,第二次用户填完验证码请求CodeAPIView校验,两次请求是完全隔离的,你不能在AuthAPIView里直接调用CodeAPIView.post传递内存变量,这部分逻辑完全错误。
修复方案
1. 修正AuthAPIView逻辑
发完验证码后直接返回成功提示,不要调用CodeAPIView的方法,等待前端第二次提交验证码的请求。同时修正登录方法里的逻辑顺序,删除验证码的代码不能放在return之后,否则永远不会执行。
2. 重写CodeAPIView的post方法
不需要额外自定义参数,从用户提交的请求里获取手机号(也就是你的username字段)和用户输入的验证码,直接查数据库匹配即可。
修正后完整代码
class AuthAPIView(APIView): def post(self, request, format=None): data = request.data username = data.get('username', None) if not username: return Response("请传入手机号", status=400) # 校验用户是否存在 try: user_obj = User.objects.get(username=username) except User.DoesNotExist: return Response("用户不存在", status=404) # 若业务逻辑就是密码等于用户名可保留,否则建议调整逻辑 password = username user = authenticate(username=username, password=password) if user and user.is_active: code = random_code_generator() # 存验证码到库,后续可自行补充过期时间字段 Code.objects.create(phone_number=user_obj, code=code) now = datetime.now() current_time = now.strftime("%H:%M:%S") hour = current_time.split(":")[0] minute = current_time.split(":")[1] send(str(username), code, int(hour), int(minute)+2) # 直接返回成功,等待前端提交验证码的二次请求 return Response("验证码发送成功") return Response("用户状态异常", status=400) @staticmethod def login(request, user, user_obj, code): login(request, user) # 用get_or_create避免首次登录无Token报错 token, _ = Token.objects.get_or_create(user=user) # 先删除已使用的验证码再返回 Code.objects.filter(phone_number=user_obj, code=code).delete() return Response(token.key) class CodeAPIView(APIView): def post(self, request): # 从请求中获取手机号和用户输入的验证码 username = request.data.get('username') input_code = request.data.get('code') if not username or not input_code: return Response("请传入手机号和验证码", status=400) # 校验用户和对应验证码是否存在 try: user_obj = User.objects.get(username=username) # 后续可补充过期时间过滤,只校验未过期的验证码 saved_code = Code.objects.filter(phone_number=user_obj, code=input_code).first() except User.DoesNotExist: return Response("用户不存在", status=404) if not saved_code: return Response("验证码错误", status=400) # 校验通过调用登录逻辑 user = authenticate(username=username, password=username) return AuthAPIView.login(request, user, user_obj, input_code)
其他优化建议
- 存储验证码时新增过期时间字段,校验时过滤已过期的验证码,避免验证码永久有效
- 增加验证码发送频率限制,避免同一个手机号短时间内重复发送
- 新增验证码错误次数限制,防止暴力破解
- 你原代码中
request.data('code')写法错误,request.data是字典类型,需要用request.data.get('code')或者request.data['code']调用
内容的提问来源于stack exchange,提问作者user15446178
相关产品推荐
相关产品推荐

