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

Django注册功能本地正常 单元测试报password非空约束错误

问题根源

你报错的核心原因出在注册接口的逻辑漏洞:

  • 当你调用无参数的POST请求测试空数据注册场景时,password和confirm_password取值都为None,None == None的判断结果为真,代码会直接进入用户创建逻辑
  • 此时你传入create方法的password参数为None,而用户表的password字段是非空约束,直接触发NOT NULL报错
  • 本地运行没报错是因为你正常提交注册时都会传密码参数,不会触发这个极端场景,单元测试刚好覆盖了这个逻辑漏洞

其他隐藏问题

  1. 没有做必填字段校验:用户名、密码、邮箱、出生日期等必填字段没有做空值判断就直接写入数据库
  2. 创建用户方式错误:Django用户模型不能直接用objects.create存密码,会导致密码明文存储,应该用objects.create_user方法自动加密密码
  3. 错误状态码不规范:密码不一致返回404状态码不符合接口规范,应该返回400
  4. 拿到的first_name、last_name参数没有写入用户表

修复后的view.py代码

from rest_framework.response import Response
from rest_framework.views import APIView
from authentication.models import User as Client
class Register(APIView):
    def post(self, request):
        username = request.data.get('Username')
        first_name = request.data.get('First name')
        last_name = request.data.get('Last name')
        password = request.data.get('Password')
        confirm_password = request.data.get('Confirm password')
        date_of_birth = request.data.get('Date of birth')
        email = request.data.get('Email')
        
        # 新增必填字段校验
        if not all([username, password, confirm_password, email, date_of_birth]):
            return Response({"message": "缺少必填参数"}, 400)
        
        if password == confirm_password:
            if Client.objects.filter(username = username).exists():
                return Response({"message": "该用户名已存在"}, 400)
            elif Client.objects.filter(email = email).exists():
                return Response({"message": "该邮箱已被注册"}, 400)
            else:
                # 改用create_user方法创建用户,自动加密密码
                user= Client.objects.create_user(
                    username = username, 
                    password = password, 
                    email=email, 
                    date_of_birth=date_of_birth,
                    first_name=first_name,
                    last_name=last_name
                )
                return Response({"message":"用户创建成功"}, 201)
        else:
            # 状态码改为400
            return Response({"message": "两次输入的密码不一致"}, 400)

内容的提问来源于stack exchange,提问作者Noor ul ain Ibrahim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:45:05