Django调用validate_password校验密码时password为真值却报NoneType无lower属性错误
问题根因
你传给validate_password的password_validators列表中传入的是校验器类本身,没有完成实例化,最终导致参数传递错位:
Django密码校验逻辑要求password_validators列表传入的是校验器实例对象,当你直接传入类调用validator.validate(password, user)时,类方法的第一个self参数会接收你传入的密码值'Bingo',方法定义的第二个参数password实际接收到的是未传值的user默认值None,所以调用password.lower()会抛出空对象属性错误,和你调试日志的表现完全吻合。
修复方案
- 给校验器类添加括号完成实例化,修改
validate_password调用代码:
validate_password(password, password_validators=[ CommonPasswordValidator(), NumericPasswordValidator() ])
- 修正异常捕获逻辑,Django原生
validate_password抛出的是django.contrib.auth.password_validation.ValidationError,不是DRF的serializers.ValidationError,需要调整捕获逻辑同时修正你原有代码的无效分支:
# 先导入Django原生的密码校验异常 from django.contrib.auth.password_validation import ValidationError as DjangoValidationError # 校验逻辑调整 def validate(self, data): username = data['username'] password = data['password'] try: validate_password(password, password_validators=[ CommonPasswordValidator(), NumericPasswordValidator() ]) except DjangoValidationError: # 原代码中pass后直接抛错,等于用户名等于密码的判断完全无效,需要调整判断逻辑 if username != password: raise serializers.ValidationError("Invalid password") return data
内容的提问来源于stack exchange,提问作者binny
相关产品推荐
相关产品推荐

