You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 19:45:03