Django注册功能本地正常 单元测试报password非空约束错误
问题根源
你报错的核心原因出在注册接口的逻辑漏洞:
- 当你调用无参数的POST请求测试空数据注册场景时,
password和confirm_password取值都为None,None == None的判断结果为真,代码会直接进入用户创建逻辑 - 此时你传入
create方法的password参数为None,而用户表的password字段是非空约束,直接触发NOT NULL报错 - 本地运行没报错是因为你正常提交注册时都会传密码参数,不会触发这个极端场景,单元测试刚好覆盖了这个逻辑漏洞
其他隐藏问题
- 没有做必填字段校验:用户名、密码、邮箱、出生日期等必填字段没有做空值判断就直接写入数据库
- 创建用户方式错误:Django用户模型不能直接用
objects.create存密码,会导致密码明文存储,应该用objects.create_user方法自动加密密码 - 错误状态码不规范:密码不一致返回404状态码不符合接口规范,应该返回400
- 拿到的
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
相关产品推荐
相关产品推荐

