问题
在django项目有如下场景:使用django-redis从redis中读取数据并且与请求数据完成比对,比如短信验证码的比对。
依赖包:
django-redis==4.11.0
djangorestframework==3.11.0
SMSCodeView.check_SMSCode
方法:
def check_SMSCode(mobile):
"""
获取短信验证码
:param mobile:
:return:
"""
conn = get_redis_connection('verify_code')
real_sms = conn.get(f'sms_code_{mobile}').decode()
return real_sms
首先,当我们使用django-redis从redis中取数据时,得到的数据是byte类型,所以需要使用decode()
处理。此时,real_sms
得到的是str
类型。
校验字段的hook:
def validate(self, attrs):
"""
验证密码及短信验证码
:param attrs:
:return:
"""
# 密码
if attrs['password'] != attrs['password2']:
raise serializers.ValidationError('两次密码不一致')
# 短信验证码
real_sms_code = SMSCodeView.check_SMSCode(attrs['mobile'])
# print(real_sms_code)
# print(type(real_sms_code))
# print(type(attrs['sms_code']))
# print(int(attrs['sms_code']))
if real_sms_code is None:
raise serializers.ValidationError('短信验证码过期')
if int(real_sms_code) != int(attrs['sms_code']):
raise serializers.ValidationError('短信验证码错误')
return attrs
因此,代码块中的real_sms_code
是str
类型,而attrs['sms_code']
也是str
类型。bug发生前,我想当然的认为,他们本质都是短信验证码,只不过是str
类型,因此可以直接比对是否相等。但是项目运行后一直在报错,并且提示短信验证码错误
。当我print
相关对象后,才发现了问题。
print
结果:
355888
<class 'str'>
<class 'str'>
355888
显然,redis返回给我们的字符串多一个空格。测试了短信验证码生成的逻辑代码后,发现是错误书写f-string时带来的问题。
import random
print(f'{random.randint(0, 999999):06}')
print(f'{random.randint(0, 999999): 06}')
输出:
779392
200457
所以,一定不要随便加空格!
小结
Python自身的特性保证了代码的简洁书写,但是也在一定程度上增加了debug的成本。建议大家好好利用Python类型注解来构建代码。
项目地址:https://github.com/LMFrank/django_library