Django项目用户注册功能(完)

一、注册功能(完)

1.业务流程分析

  • 对校验进行校验
    • 校验用户名
    • 校验密码
    • 校验手机号码
    • 校验短信验证码
  • 新建数据库记录

2、接口设计

2.1 接口说明

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

2.2 参数说明

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

注意每个表单页面都要自己加 {% csrf_token %}
2.3 返回的结果:
返回的结果:

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

3.编写代码

既然是框架就要符合框架的逻辑,视图的views 只调用相应的模板即可,校验在forms 表单校验,因此 在 user 下面新建forms.py

user_views 新增代码

......
from .forms import RegisterForm
from utils.res_code import json_response,Code
from .models import User


# 调用模板 检验数据 创建数据库记录
    def post(self,request):
        # 1. 校验数据
        form = RegisterForm(request.POST)
        if form.is_valid():
            # 2. 创建数据库记录
            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.values():
                # item 也是一个列表,所以把错误信息放在item的第一位
                err_msg_list.append(item[0])
            err_msg_str = '/'.join(err_msg_list)
            return json_response(errno=Code.PARAMERR, errmsg=err_msg_str)

user_forms 代码:

from django import forms
from django_redis import get_redis_connection


from verification import constants
from .models import User
from verification.forms import mobile_validator


class RegisterForm(forms.Form):
    '''
    用户注册表单
    '''
    # 获取字段内容
    username = forms.CharField(label='用户名',max_length=20,min_length=5,error_messages={
        'max_length':'用户名长度要小于20',
        'min_length':'用户名长度至少5个字符',
        'required':'用户名不能为空',
    })
    password = forms.CharField(label='密码', max_length=20, min_length=6, error_messages={
        'max_length': '密码长度要小于20',
        'min_length': '密码长度至少6个字符',
        'required': '密码不能为空',
    })
    password_repeat = forms.CharField(label='重复密码', max_length=20, min_length=6, error_messages={
        'max_length': '密码长度要小于20',
        'min_length': '密码长度至少6个字符',
        'required': '密码不能为空',
    })
    mobile = forms.CharField(label='手机号码', max_length=11, min_length=11,validators=[mobile_validator,], error_messages={
        'max_length': '请输入正确的11位手机号码',
        'min_length': '请输入正确的11位手机号码',
        'required': '手机号码不能为空',
    })
    sms_code = forms.CharField(label='短信验证码', max_length=constants.SMS_CODE_LENGTH, min_length=constants.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():
            raise forms.ValidationError('用户名已注册,请重新输入')
        return username

    def clean_mobile(self):
        '''
        校验手机号码
        :return:
        '''
        mobile = self.cleaned_data.get('mobile')
        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')
        mobile = clean_data.get('mobile')

        redis_conn = get_redis_connection(alias='verify_code')
        real_code =  redis_conn.get('sms_text_%s'%(mobile))
        print(real_code,'   ',sms_code)
        if (not real_code) or ( real_code.decode('utf-8') != sms_code ) :
            raise forms.ValidationError('短信验证码错误')


这里注意一点: clean_字段名 跟 clean 的区别
clean_字段名: 你写多少就执行多少 记得要return 字段名
clean: 只要有一部分不通过就不会往下执行

4. 前端部分

// 6. 注册
    let $submitBtn = $('.register-btn');
    $submitBtn.click((e)=>{
        //阻止默认提交
        e.preventDefault();
        //检查各参数状态
        if (!isUsernameReady) {
            fnCheckUsername();
            return
        }
        if (!isPasswordReady){
            fnCheckPassword();
            return
        }
        if (!isMobileReady){
            fnCheckMobile();
            return
        }

        // 检验短信验证码
        let sSmsCode = $('input[name="sms_captcha"]').val();
        if (sSmsCode === ''){
            message.showError('短信验证码不能为空,请重新输入');
            return
        }
        if (!(/^\d{4}$/).test(sSmsCode)){
            message.showError('短信验证码长度不正确,必须是4位数字');
            return
        }

        // 发送ajax
        $
            .ajax({
                url:'/user/register/',
                type:'POST',
                data:{
                    mobile : $mobile.val(),
                    username:$username.val(),
                    password:$('input[name="password"]').val(),
                    password_repeat:$passwordRepeat.val(),
                    sms_code:sSmsCode,
                },
                dataType:'json',
            })
            .done((res)=>{
                if(res.errno === '0'){
                    message.showSuccess(res.errmsg);
                    //跳转的登录页面
                    setTimeout(()=>{
                        window.location.href='/user/login/'
                    },1500)

                }else {
                    //注册失败
                    message.showError(res.errmsg);
                }
            })
            .fail((res)=>{
                message.showError('服务器连接超时,请重试');
            })
    })

5.短信验证码

在 verification_views 之前留下的接口处增加以下代码

# 新增导入包
from utils.yuntongxun.sms import CCP
#发送的代码
ccp = CCP()
            try:
                res = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_EXPIRES], "1")
                if res == 0:
                    logger.info('发送短信验证码[正常][mobile: %s sms_code: %s]' % (mobile, sms_code))
                else:
                    logger.error('发送短信验证码[失败][moblie: %s sms_code: %s]' % (mobile, sms_code))
                    return json_response(errno=Code.SMSFAIL, errmsg=error_map[Code.SMSFAIL])
            except Exception as e:
                logger.error('发送短信验证码[异常][mobile: %s message: %s]' % (mobile, e))
                return json_response(errno=Code.SMSERROR, errmsg=error_map[Code.SMSERROR])

附上效果图


01.jpg
02.jpg
03.jpg
04.jpg

最后的最后

 $ git add .
 $ git commit -m 'update projects'
 $ git push origin master

你可能感兴趣的:(Django项目用户注册功能(完))