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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 03:53:16