一副砍、注冊功能(完)
1.業(yè)務流程分析
- 對校驗進行校驗
- 校驗用戶名
- 校驗密碼
- 校驗手機號碼
- 校驗短信驗證碼
- 新建數據庫記錄
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
# 調用模板 檢驗數據 創(chuàng)建數據庫記錄
def post(self,request):
# 1. 校驗數據
form = RegisterForm(request.POST)
if form.is_valid():
# 2. 創(chuàng)建數據庫記錄
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('兩次輸入的密碼不一致媳瞪,請重新輸入')
######################################
# 如果上面這個判斷驗證不通過,下面代碼不會執(zhí)行
###################################
## 校驗短信驗證碼
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 的區(qū)別
clean_字段名:
你寫多少就執(zhí)行多少 記得要return 字段名
clean:
只要有一部分不通過就不會往下執(zhí)行
4. 前端部分
// 6. 注冊
let $submitBtn = $('.register-btn');
$submitBtn.click((e)=>{
//阻止默認提交
e.preventDefault();
//檢查各參數狀態(tài)
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
}
// 發(fā)送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
#發(fā)送的代碼
ccp = CCP()
try:
res = ccp.send_template_sms(mobile, [sms_code, constants.SMS_CODE_EXPIRES], "1")
if res == 0:
logger.info('發(fā)送短信驗證碼[正常][mobile: %s sms_code: %s]' % (mobile, sms_code))
else:
logger.error('發(fā)送短信驗證碼[失敗][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('發(fā)送短信驗證碼[異常][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