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

Django REST Framework登录API Post方法IF语句无法执行问题

问题描述

使用Django REST Framework开发登录API,用于验证数据库中是否存在指定用户数据:

  • 数据库存在正确数据:pengerja_id=123、password=123
  • 测试错误数据:pengerja_id=555、password=555

测试时发现:

  • 输入错误pengerja_id(如555)时,queryset.exists()返回false,正常执行else逻辑返回404
  • 输入正确pengerja_id(123)时,serializer.is_valid()验证不通过,直接返回400错误,后续代码完全不执行
  • 同项目中的InsertNewMemberView功能正常,代码逻辑与当前登录视图类似
问题分析

核心问题出在AuthorizeMemberSerializer的选型上:
当前使用ModelSerializer作为登录验证的序列化器,而ModelSerializer会自动继承模型字段的验证规则。由于模型中pengerja_id是主键且设置了unique=True,ModelSerializer会默认将其视为“创建新数据”的场景,自动验证该pengerja_id是否已存在——当输入已存在的123时,唯一性验证失败,直接导致serializer.is_valid()返回False,触发400错误。

而InsertNewMemberView功能正常,是因为该视图的业务是创建新用户,测试时输入的都是未存在的pengerja_id,不会触发唯一性验证失败的情况。

另外,当前登录逻辑仅验证pengerja_id是否存在,未验证输入的password是否与数据库匹配,存在功能漏洞。

解决方案

针对登录场景的特殊性,需要:

  1. 改用普通Serializer替代ModelSerializer,避免继承模型的唯一性验证规则,仅做输入格式校验
  2. 完善登录逻辑,同时验证pengerja_id存在性和密码正确性

修改后的代码

serializers.py

调整AuthorizeMemberSerializer为普通序列化器:

from rest_framework import serializers
from .models import COOL_YOUTH_MEMBER

# 保留其他序列化器不变...

class AuthorizeMemberSerializer(serializers.Serializer):
    pengerja_id = serializers.CharField(max_length=255)
    password = serializers.CharField(max_length=255)

views.py

完善AuthorizeMemberView的登录验证逻辑:

# 保留其他视图不变...

class AuthorizeMemberView(APIView):
    serializer_class = AuthorizeMemberSerializer

    def post(self, request, format=None):
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            pengerja_id = serializer.data.get('pengerja_id')
            password = serializer.data.get('password')
            
            # 通过get方法直接获取用户,不存在则抛出异常
            try:
                member = COOL_YOUTH_MEMBER.objects.get(pengerja_id=pengerja_id)
                # 验证密码是否匹配
                if member.password == password:
                    return Response({'Success':'User Verified'}, status=status.HTTP_202_ACCEPTED)
                else:
                    return Response({'Login Failed':'Incorrect password'}, status=status.HTTP_401_UNAUTHORIZED)
            except COOL_YOUTH_MEMBER.DoesNotExist:
                return Response({'Login Failed':'User not registered'}, status=status.HTTP_404_NOT_FOUND)
            
        # 返回具体的验证错误信息,便于调试
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
额外提示
  • 生产环境中禁止明文存储密码,建议使用Django自带的make_password和check_password方法加密验证密码
  • 可以考虑使用DRF自带的Authentication类或第三方库实现更规范的登录认证流程

内容的提问来源于stack exchange,提问作者Lukas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 07:25:34