当输入手机号时需要检测该手机号是否注册过,然后点击登录时一起将手机号和验证吗提交给后端,再次校验手机号和验证码。
这里使用form的方式将字段渲染再前端,在form中校验字段。

首先将字段传入到模板中:

views.py:

def login_sms(request):
    if request.method == 'GET':
        form = LoginSmsForm(request.GET)
        return render(request, 'user/login_sms.html', dict(form=form))

login.html:

<div class="container">
        <div class="row">
            <div class="col-md-4 col-md-offset-4">
                <div class="account">
                    <h2 class="text-center">短信登录</h2>
                    <form id="form_data">
                        {% csrf_token %}
                        {% for field in form %}
                            {% if field.label == '验证码' %}
                                <div class="form-group">
                                    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                    <div class="row">
                                        <div class="col-xs-6">
                                            {{ field }}
                                            <span class="error_msg"></span>
                                        </div>
                                        <div class="col-xs-6">
                                            <button id="get_code" type="button" class="btn btn-default">点击获取验证码</button>
                                        </div>
                                    </div>
                                </div>
                            {% else %}
                                <div class="form-group">
                                    <label for="{{ field.id_for_label }}">{{ field.label }}</label>
                                    {{ field }}
                                    <span class="error_msg"></span>
                                </div>
                            {% endif %}
                        {% endfor %}
                         <button type="button" id="login_sms" class="btn btn-primary">登 录</button>
                        <div class="pull-right">
                            <a href="{% url 'login' %}">用户登录>>></a>
                        </div>
                    </div>
                    </form>
                </div>
            </div>
        </div>
    </div>

点击获取验证码,发送ajax请求:

// 绑定点击获取验证码的事件
    function bindGetCodeEvent(){
        $('#get_code').click(function () {
            var phoneEle = $('#id_phone');
            var phone_numbe = phoneEle.val().trim();
            var phone_reg = /^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/
            if (phone_numbe && phone_reg.test(phone_numbe)){
                phoneEle.next().text('');
                // 校验通过之后 发送 ajax 请求
                $.ajax({
                    url:'{% url "sms_code" %}',
                    type:'get',
                    // tpl:短信模板
                    data:{phone:phone_numbe, tpl:"login"},
                    success:function (res){
                        if (res.status){
                            //开启倒计时效果
                            SmsTimer();
                        }else{
                            phoneEle.next().text(res.error_msg.phone);
            }else {
                phoneEle.next().text('手机号格式不对!');
                return false

倒计时功能:

// 倒计时效果函数
    function SmsTimer() {
        // 将标签设置为不可点击的
        // jquery 的变量一般以 $ 开头
        var $btnEle = $('#get_code');
        $btnEle.prop('disable',true);
        // 设置定时器读秒效果和标签文本内容的修改
        var timer = 60;
        var t = setInterval(
            function () {
                $btnEle.text(`${timer}秒后重新发送`);
                timer--;
                // 如果小于0就将定时器清除并且将$btnEle设置为可操作
                if (timer <= 0){
                    clearInterval(t);
                    $btnEle.text('点击获取验证码');
                    $btnEle.prop('disable',false);
            1000 // 1秒中执行一次这个函数

发送登录的数据:

// 发送登录数据
    function sendLoginData() {
        // 获取用户输入的所有数据
        // 将数据发送到后端
        // 根据响应结果进行一些页面效果处理
        // 绑定点击事件
        $('#login_sms').click(function () {
            var data = $('#form_data').serialize(); //拿到form表单中的所有数据
            $.ajax({
                url: '{% url 'login_sms' %}',
                type: 'post',
                data: data,
                success:function (res) {
                    if (res.status){
                        location.href = res.path;
                    }else{
                        $.each(res.error_msg,function (k,v){
                            $('#id_' + k).next().text(v)

后端校验数据

整体数据(手机号、验证码)提交时的数据校验:

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, ])
    # 重写 init 方法接受额外参数(request)
    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'):
            # TODO 逻辑待定
        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)
        # 将验证码保存到 redis 中
        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():
            # TODO 将登录成功之后的数据保存到session中,方便后续使用
            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 官方文档和相关社区的实现方法。希望能对您有所帮助。