整体数据(手机号、验证码)提交时的数据校验:
class LoginSmsForm(BootStrapForm, forms.Form):
phone = forms.CharField(label='手机号', validators=[mobile_validate, ])
sms_code = forms.CharField(label='验证码')
def clean_phone(self):
'''手机号唯一性校验'''
phone = self.cleaned_data.get('phone')
phone_require = models.UserInfo.objects.filter(phone=phone)
if not phone_require.exists():
raise ValidationError('该手机号还没注册,请先注册!!')
return phone
def clean_sms_code(self):
'''验证码校验
* 取出 sms_code、phone
* 获取连接,从 redis 中取出 验证码
* 如果不同则抛出错误
注意点:一般局部钩子只获取当前局部变量,无法获取其他变量,如在phone中不能获取email的对象
解决方式:
phone 必须在 sms_code 校验的前面,顺序就是fields中指定的。
sms_code = self.cleaned_data.get('sms_code')
phone = self.cleaned_data.get('phone')
conn = get_redis_connection('sms_code')
code = conn.get(phone)
if code is not None:
if code.decode('utf-8') != sms_code.strip():
raise ValidationError('验证码错误!!!')
else:
raise ValidationError('验证码无效或已经超时!!')
return code
发送验证码时的数据校验:
class SendSmsForm(forms.Form):
phone = forms.CharField(label='手机号', validators=[mobile_validate, ])
def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs)
self.request = request
def clean_phone(self):
'''手机号和短信模板校验'''
tpl = self.request.GET.get('tpl')
try:
sms_template_id = settings.SMS_TEMPLATE_ID[tpl]
except:
raise ValidationError('短信模板错误!!')
phone = self.cleaned_data.get('phone')
unique_phone = models.UserInfo.objects.filter(phone=phone)
if tpl == settings.SMS_TEMPLATE_ID.get('register'):
if unique_phone.exists():
raise ValidationError('该手机号已经注册过了!')
elif tpl == settings.SMS_TEMPLATE_ID.get('login'):
if not unique_phone.exists():
raise ValidationError('该手机号还未注册过!')
elif tpl == settings.SMS_TEMPLATE_ID.get('repassword'):
else:
raise ValidationError(f'短信模板:{tpl}不存在!')
conn = get_redis_connection('sms_code')
if conn.get(phone) is not None:
raise ValidationError('已经发送过短信!!')
sms_code = '%06d' % random.randint(1, 999999)
conn.set(phone, sms_code, ex=settings.SMS_CODE_EXPIRE)
obj = MySmsSender()
obj.send(phone, sms_template_id, sms_code)
return phone
完整view试图函数:
登录:
def login_sms(request):
if request.method == 'GET':
form = LoginSmsForm(request.GET)
return render(request, 'user/login_sms.html', dict(form=form))
else:
form = LoginSmsForm(data=request.POST)
if form.is_valid():
return JsonResponse(dict(status=True, path=reverse('index')))
else:
return JsonResponse(dict(status=False, error_msg=form.errors))
发送验证码:
def sms_code(request):
'''获取手机号,校验手机号,发送短信验证码
* 格式校验
* 是否注册过
form = SendSmsForm(request, data=request.GET)
if form.is_valid():
return JsonResponse({'status': True})
else:
return JsonResponse({'status': False, 'error_msg': form.errors})
实现页面效果实现思路当输入手机号时需要检测该手机号是否注册过,然后点击登录时一起将手机号和验证吗提交给后端,再次校验手机号和验证码。这里使用form的方式将字段渲染再前端,在form中校验字段。画页面首先将字段传入到模板中:views.py:def login_sms(request): if request.method == 'GET': form = LoginSmsForm(request.GET) return render(request,
# 发送短信
def request2(mobile,num, m="GET"):
appkey = 'a0d6d54cb54e74478f0eca04bdef'#'abf6ecebfa954395dad7dcc6be7c8'
url...
django中有关于登录验证的第三方模块,大家可以自己去搜搜,这里说一下自定义验证码登录的情况(可以参考http://www.cnblogs.com/alex3714/articles/6662365.html这篇文章)。
我们生成的验证码图片在发送给html前要先存放,可以有两种地方:
1.内存中,我们开发环境下时可以这样用,但是在生产时最好别这样,因为访问量太高的话,你内存就等着爆吧;
url = ‘http://106.ihuyi.com/webservice/sms.php?method=Submit’
mobile = ‘xxxxxx’ #电话号
account= ‘xxxxx’ #上面的APIID
password = ‘xxxxx’ #为上图的APIKEY...
在verify/migrations 新建一个serlalizers.py:
from rest_framework import serializers
from django_redis import get_redis_connection
class MsgCodeSerializer(serializers.Serializer):
imagecode_id = serializ...
作用就是存放html文件在项目的settings.py文件中配置模板,如下图:
5,在项目根目录下创建static目录
作用就是存放css/图片/js等文件在项目的settings.py文件中配置static文件,如下图
6,数据库
您好,要实现 Django 手机短信验证码功能,可以借助第三方短信服务商提供的 API 接口来实现。具体步骤如下:
1. 在第三方短信服务商注册账号并开通短信服务,获取 API 接口。
2. 在 Django 项目中安装 requests 库(用来发送 HTTP 请求),并在 settings.py 配置好 API 接口参数(例如短信签名、短信模板等)。
3. 编写后端逻辑代码,包括生成随机验证码、将验证码和手机号码(或其他需要发送短信的信息)传递给 API 接口并发送短信。
4. 在前端页面加入验证表单和获取短信验证码按钮。
5. 在后端接收前端传递的验证码和手机号码,进行验证和校验,返回验证结果给前端。
具体实现过程可以参考 Django 官方文档和相关社区的实现方法。希望能对您有所帮助。