二十. 用户注册 — 实现注册功能 2020-04-17

7 篇文章 0 订阅

二十. 用户注册 — 实现注册功能

注:该篇文章接上一篇 十九 .用户注册 — 短信验证码实现
在上一篇文章我们实现了用户注册中的短信验证码功能,在这一章实现注册功能
实现注册要完成的图表
在这里插入图片描述
实现注册模块的整体流程
在这里插入图片描述
根据流程图总结注册业务包含如下功能

  • 注册页面
  • 图片验证码
  • 用户名检测是否注册
  • 手机号检测是否注册
  • 短信验证码
  • 注册保存用户数据

九、注册功能

1.业务流程分析

  1. 判断用户名是否为空,是否已注册
  2. 判断密码是否为空,格式是否正确
  3. 判断两次密码是否一致
  4. 判断手机号码是否为空,格式是否正确
  5. 判断短信验证码是否为空,格式是否正确,是否与真实短信验证码相同

2.接口设计

接口说明:

类目说明
请求方法POST
url定义/user/register/
参数格式表单

注意:post请求,前端请求要带上csrf token

参数说明:

参数名类型是否必须描述
username字符串用户输入的用户名
password字符串用户输入的密码
password_repeat字符串用户输入的重复密码
mobile字符串用户输入的手机号码
sms_code字符串用户输入的短信验证码

返回结果:

{
    "errno": "0", 
 	"errmsg": "恭喜您,注册成功!", 
}

3.后端代码

  1. user/views.py
from django.shortcuts import render
from django.views import View
from .forms import RegisterForm
from .models import User
from utils.json_res import json_response
from utils.res_code import Code,error_map

# Create your views here.
def login(request):
    return render(request, 'user/login.html')

# def register(request):
#     return render(request,'user/register.html')

class RegisterView(View):
    def get(self, request):
        return render(request, 'user/register.html')

    def post(self,requset):
        # 写一个表单,用于post接口,用于验证填写的信息
        form = RegisterForm(requset.POST)
        if form.is_valid():
            #验证form表单
            #获取表单信息
            username = form.cleaned_data.get('username')
            password = form.cleaned_data.get('password')
            mobile = form.cleaned_data.get('mobile')
            #存储到用户模型中
            User.objects.create_user(username = username,password = password,mobile = mobile)
            return json_response(errmsg='恭喜你注册成功')
        else:
            #定义错误表信息
            # 将表单的报错信息进行拼接
            err_msg_list = []
            for item in form.errors.get_json_data().values():
                err_msg_list.append(item[0].get('message'))
                # print(item[0].get('message'))   # for test
            err_msg_str = '/'.join(err_msg_list)  # 拼接错误信息为一个字符串

            return json_response(errno=Code.PARAMERR, errmsg=err_msg_str)


  1. user/forms.py代码:
import re   # 用于验证信息格式
from django_redis import get_redis_connection  # 连接redis库
from  .models import User    # 导入用户库模型
from  django import forms
from  verification.constants import SMS_CODE_LENGTH


class RegisterForm(forms.Form):
    username = forms.CharField(label='用户名', max_length=20, min_length=5,
                               error_messages={
                                   'max_length': '用户名长度要小于20',
                                   'min_length': '用户名长度要大于4',
                                   'required': '用户名不能为空'
                               })
    password = forms.CharField(label='密码', max_length=20, min_length=6,
                               error_messages={
                                   'max_length': '密码长度要小于20',
                                   'min_length': '密码长度要大于5',
                                   'required': '用户名不能为空'
                               })
    password_repeat = forms.CharField(label='确认密码', max_length=20, min_length=6,
                                      error_messages={
                                          'max_length': '密码长度要小于20',
                                          'min_length': '密码长度要大于5',
                                          'required': '用户名不能为空'
                                      })
    mobile = forms.CharField(label='手机号码', max_length=11, min_length=11,
                             error_messages={
                                 'max_length': '手机号码长度有误',
                                 'min_length': '手机号码长度有误',
                                 'required': '手机号码不能为空'
                             })
    sms_code = forms.CharField(label='短信验证码', max_length=SMS_CODE_LENGTH, min_length=SMS_CODE_LENGTH,
                               error_messages={
                                   'max_length': '短信验证码长度有误',
                                   'min_length': '短信验证码长度有误长度有误',
                                   'required': '短信验证码不能为空'
                               })

    def clean_username(self):
        """
        校验用户名
        :return:
        """
        username = self.cleaned_data.get('username')
        if User.objects.filter(username=username).exists():
            return forms.ValidationError('用户名已存在!')
        return username

    def clean_mobile(self):
        """
        校验手机号
        :return:
        """
        mobile = self.cleaned_data.get('mobile')
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            raise forms.ValidationError('手机号码格式不正确')

        if User.objects.filter(mobile=mobile).exists():
            raise forms.ValidationError('手机号码已注册!')

        return mobile

    def clean(self):
        """
        校验,密码,和短信验证码
        :return:
        """
        clean_data = super().clean()
        # 校验密码是否一致
        password = clean_data.get('password')
        password_repeat = clean_data.get('password_repeat')
        if password != password_repeat:
            raise forms.ValidationError('两次密码不一致!')

        # 校验短信验证码
        sms_code = clean_data.get('sms_code')
        moblie = clean_data.get('mobile')
        # 获取rides中缓存的验证码,get_redis_connection() -- 指定与哪个数据库建立连接
        redis_conn = get_redis_connection(alias='verify_code')
        real_code = redis_conn.get('sms_text_{}'.format(moblie))
        if (not real_code) or (real_code.decode('utf-8') != sms_code):
            raise forms.ValidationError('短信验证码错误!')



4.前端js代码

$(function () {

    // 定义状态变量
    //判断状态是false还是ture,如果是ture就直接引用
    let isUsernameReady = false,
        isPasswordReady = false,
        isMobileReady = false,
        isSmsCodeReady = false;

    let $img = $('.form-contain .form-item .captcha-graph-img img');
    // 1.点击刷新图像验证码
    $img.click(function () {
        $img.attr('src', '/image_code/?rand=' + Math.random())
    });

    // 2.鼠标离开用户名输入框校验用户名
    let $username = $('#username'); //获取前端页面中的username框
    $username.blur(fnCheckUsername); //blur是鼠标离开事件

    //鼠标离开username触发函数fnCheckUsername
    function fnCheckUsername() {
        isUsernameReady = false;            //校验用户名,没填入用户名为false
        let sUsername = $username.val();    // 获取用户名字符串
        if (sUsername === '') {
            // 如果用户名为空,返回消息
            message.showError('用户名不能为空')
            return
        }
        if (!(/^\w{5,20}$/).test(sUsername)) {
            //检测用户名长度
            message.showError('请输入5-20个字符的用户名');
            return
        }
        $.ajax({
            url: '/username/' + sUsername + '/',      //发送请求的地址
            type: 'GET',                              //请求方式
            dataType: 'json',                         //预期服务器返回的数据类型
            success: function (data) {
                // data 由服务器返回的数据,我们这里是json类型
                if (data.data.data.count !== 0) {
                    //根据json的数据结构的到用户数量
                    message.showError(data.data.data.username + '已经注册,请重新输入!')
                } else {
                    message.showInfo(data.data.username + '可以正常使用!');
                    isUsernameReady = true
                }
            },
            error: function (xhr, msg) {
                //请求失败时被调用的函数
                message.showError('服务器超时,请重试!')
            }
        });
    }

    // 3.检测密码是否一致
     let $passwordRepeat = $('input[name="password_repeat"]'); //获取前端input[name="password_repeat"] 中的内容(二次密码)
     $passwordRepeat.blur(fnCheckPassword);     //blur是鼠标离开事件

    //鼠标离开username触发函数fnCheckPassword
     function fnCheckPassword() {
        isPasswordReady = false;   //校验密码,没填入密码为false
        let password = $('input[name="password"]').val();   // 获得密码字符串
        let passwordRepeat = $passwordRepeat.val();      // 获取用户二次密码字符串
        if (password === '' || passwordRepeat === '') {
            message.showError('密码不能为空');
            return
        }
        if (password !== passwordRepeat) {
            message.showError('两次密码输入不一致');
            return
        }
        if (password === passwordRepeat) {
            isPasswordReady = true
        }
    }

    // 4.检查手机号码是否可用
    let $mobile = $('input[name="mobile"]'); //获取前端input[name="mobile"] 中的内容(手机密码)
    $mobile.blur(fnCheckMobile);
    //鼠标离开username触发函数fnCheckMobile
    function fnCheckMobile () {
        isMobileReady = true;
        let sMobile = $mobile.val(); // 获得手机字符串
        if(sMobile === ''){
            message.showError('手机号码不能为空');
            return
        }
        if(!(/^1[3-9]\d{9}$/).test(sMobile)){
            message.showError('手机号码格式不正确');
            return
        }

        $.ajax({
            url: '/mobile/' + sMobile + '/',
            type: 'GET',
            dataType: 'json',
            success: function (data) {
                if(data.data.count !== 0){
                    message.showError(data.data.mobile + '已经注册,请重新输入!')
                }else {
                    message.showInfo(data.data.mobile + '可以正常使用!');
                    isMobileReady = true
                }
            },
            error: function (xhr, msg) {
                message.showError('服务器超时,请重试!')
            }
        });

    }

  // 5.发送手机验证码
    let $smsButton = $('.sms-captcha');
    $smsButton.click(function (){
        let sCaptcha = $('input[name="captcha_graph"]').val();
        if (sCaptcha === '') {
            message.showError('请输入验证码');
            return
        }
        if (!isMobileReady) {
            fnCheckMobile();
            return
        }

        $.ajax({
            url: '/sms_code/',
            type: 'POST',
            data: {
                mobile: $mobile.val(),
                captcha: sCaptcha
            },
            dataType: 'json',
            success: function (data) {
                if (data.errno !== '0') {
                    message.showError(data.errmsg)
                } else {
                    message.showSuccess(data.errmsg);
                    let num = 60;
                    //设置计时器
                    let t = setInterval(function () {
                        if (num === 1) {
                            clearInterval(t)
                        }
                    })
                }
            },
            error: function (xhr, msg) {
                message.showError('服务器超时,请重试!')
            }
        });
    });
 // 6.注册
    let $submitBtn = $('.register-btn');
    $submitBtn.click(function (e) {
        //阻止默认提交
        e.preventDefault();
        // 1.检查用户名
        if(!isUsernameReady){
            fnCheckUsername();
            return
        }
        // 2.检查密码
        if(!isPasswordReady){
            fnCheckPassword();
            return
        }
        // 3.检查电话号码
        if(!isMobileReady){
            fnCheckMobile();
            return
        }
        // 4.检查短信验证码
        let sSmsCode = $('input[name="sms_captcha"]').val();//获取前端input[sms_captcha] 中的内容(短信验证码)
        if(sSmsCode === ''){
            message.showError('短信验证码不能为空!');
            return
        }
        if(!(/^\d{4}$/).test(sSmsCode)){
            message.showError('短信验证码长度不正确,必须是4位数字!');
            return
        }

        $.ajax({
            url: '/register/',
            type: 'POST',
            data:{
                username: $username.val(),
                password: $('input[name="password"]').val(),
                password_repeat: $passwordRepeat.val(),
                mobile: $mobile.val(),
                sms_code: sSmsCode
            },
            dataType: 'json',
            success: function (res) {
                if(res.errno === '0'){
                    message.showSuccess('恭喜您,注册成功!');
                    setTimeout(function () {
                        //注册成功后重定向到登录页面
                        window.location.href = '/login/'
                    }, 3000)
                }else{
                    //注册失败
                    message.showError(res.errmsg)
                }
            },
            error: function () {
                message.showError('服务器超时,请重试!')
            }
        })

    });
});





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值