使用Django REST Framework发送OTP时出现AttributeError错误排查
错误分析与修复方案
1. 核心错误:实例方法调用方式错误
你在views.py中直接通过类调用实例方法OTPGenerator.generate_otp(phone_number),这会导致方法内的self被替换成传入的phone_number字符串(而非OTPGenerator类的实例)。字符串对象没有_otp属性,因此触发AttributeError。
修复代码:
# views.py中修改调用逻辑 otp_generator = services.OTPGenerator(phone_number) otp = otp_generator.generate_otp()
2. Redis取值键名错误
services.py的generate_otp方法中,你用固定字符串'phone_number'作为Redis的键,这会导致始终取同一个固定键的值,而非当前用户手机号对应的OTP。
修复代码:
# services.py中修改Redis取值逻辑 otp_code = redis_conf.get(self.phone_number)
3. __str__方法属性引用错误
services.py的__str__方法返回self.otp,但类实例中定义的OTP属性是self._otp,这会引发另一个AttributeError。
修复方案二选一:
- 直接返回
_otp:
def __str__(self): return self._otp
- 给
_otp添加属性装饰器,支持self.otp访问:
@property def otp(self): return self._otp def __str__(self): return self.otp
4. 序列化器验证逻辑不规范
serializers.py中的phone_validation方法验证失败时返回ValueError对象,不符合Django REST Framework的验证规范,且未绑定到字段的验证器列表中,不会自动执行。
修复代码:
# serializers.py中修改验证逻辑 from rest_framework.exceptions import ValidationError class GenerateOTPSerializer(serializers.Serializer): def phone_validation(self, phone_number): if phone_number[0] == '0' and phone_number[1] == '9' and len(phone_number) == 11 and phone_number.isnumeric(): return phone_number else: raise ValidationError('手机号必须是11位数字,且以09开头') phone_number = serializers.CharField(max_length=11, required=True, validators=[phone_validation])
内容的提问来源于stack exchange,提问作者Ali Mohammadnia
相关产品推荐
相关产品推荐

