用戶註冊功能實現 二
目的:
1、用戶名校驗功能實現
2、手機號碼校驗功能實現
應用技術:
1、前端:js(jQuery框架)、ajax(前後端交互)、
2、後端:django接口設計(json)
接口模式化
一、json響應數據結構設計
1.結構設計
實際項目是多人協同開發,特別是前後端交互,後端返回數據結構要一致。
{"errno": "0", "errmsg": "OK", "data": {...}}
字段 | 類型 | 說明 |
---|---|---|
errno | 字符串 | 錯誤編碼 |
errmsg | 字符串 | 錯誤信息 |
data | 返回數據 |
在項目根目錄中utils的db文件夾下創建res_code.py文件,用於定義錯誤編碼,代碼如下:
class Code:
OK = "0"
DBERR = "4001"
NODATA = "4002"
DATAEXIST = "4003"
DATAERR = "4004"
METHERR = "4005"
SMSERROR = "4006"
SMSFAIL = "4007"
SESSIONERR = "4101"
LOGINERR = "4102"
PARAMERR = "4103"
USERERR = "4104"
ROLEERR = "4105"
PWDERR = "4106"
SERVERERR = "4500"
UNKOWNERR = "4501"
error_map = {
Code.OK: "成功",
Code.DBERR: "數據庫查詢錯誤",
Code.NODATA: "無數據",
Code.DATAEXIST: "數據已存在",
Code.DATAERR: "數據錯誤",
Code.METHERR: "方法錯誤",
Code.SMSERROR: "發送短信驗證碼異常",
Code.SMSFAIL: "發送短信驗證碼失敗",
Code.SESSIONERR: "用戶未登錄",
Code.LOGINERR: "用戶登錄失敗",
Code.PARAMERR: "參數錯誤",
Code.USERERR: "用戶不存在或未激活",
Code.ROLEERR: "用戶身份錯誤",
Code.PWDERR: "密碼錯誤",
Code.SERVERERR: "內部錯誤",
Code.UNKOWNERR: "未知錯誤",
}
2.快捷方法
爲了方便定義一個快捷方法,在utils目錄db文件夾res_code.py文件加入代碼如下:
from django.http import JsonResponse
from .res_code import Code
def json_response(errno=Code.OK, errmsg='', data=None, kwargs=None):
json_dict = {
'errno': errno,
'errmsg': errmsg,
'data': data
}
if kwargs and isinstance(kwargs, dict) :
json_dict.update(kwargs)
return JsonResponse(json_dict)
二、判斷用戶是否註冊功能實現
1.接口設計
接口說明:
類目 | 說明 |
---|---|
請求方式 | GET |
url定義 | /username/(?P\w{5,20})/ |
參數格式 | url路徑參數 |
參數說明:
參數名 | 類型 | 是否必須 | 描述 |
---|---|---|---|
username | 字符串 | 是 | 輸入的用戶名 |
返回結果:
{
"errno": "0",
"errmsg": "OK",
"data": {
"username": "username", # 查詢的用戶名
"count": 1 # 用戶名查詢的數量
}
}
2.後端代碼
- 創建app verification專門用來處理驗證
- verification/views.py代碼
from user.models import User
from utils.json_res import json_response
#檢查用戶名
def check_username_view(request, username):
data = {
'username': username,
'count': User.objects.filter(username=username).count()
}
return json_response(data=data)
- verification/urls.py代碼
from django.urls import path, re_path
from . import views
# url的命名空間
app_name = 'verification'
#使用re_path,會進行自動re匹配,不滿足的不會訪問
urlpatterns = [
path('image_code/', views.image_code_view, name='image_code'),
re_path('username/(?P<username>\w{5,20})/', views.check_username_view, name='check_username'),
]
3.前端頁面代碼
user/register.html代碼如下:
(後面js 使用id選擇器,這裏的用戶名input 要加入id=‘username’)
{% extends 'base/base.html' %}
{% load static %}
{% block title %}註冊{% endblock title %}
{% block link %}
<link rel="stylesheet" href="{% static 'css/user/auth.css' %}">
{% endblock link %}
{% block main_start %}
<main id="container">
<div class="register-contain">
<div class="top-contain">
<h4 class="please-register">請註冊</h4>
<a href="javascript:void(0);" class="login">立即登錄 ></a>
</div>
<form action="" method="post" class="form-contain">
<div class="form-item">
<input type="text" placeholder="請輸入用戶名" id="username" name="username" class="form-control" >
</div>
<div class="form-item">
<input type="password" placeholder="請輸入密碼" name="password" class="form-control">
</div>
<div class="form-item">
<input type="password" placeholder="請輸入確認密碼" name="password_repeat" class="form-control">
</div>
<div class="form-item">
<input type="tel" placeholder="請輸入手機號" name="telephone" class="form-control" autocomplete="off">
</div>
<div class="form-item">
<input type="text" placeholder="請輸入圖形驗證碼" name="captcha_graph" class="form-captcha">
<a href="javascript:void(0);" class="captcha-graph-img">
<img src="{% url 'verification:image_code' %}" alt="驗證碼" title="點擊刷新">
</a>
</div>
<div class="form-item">
<input type="text" placeholder="請輸入短信驗證碼" name="sms_captcha" class="form-captcha" autocomplete="off">
<a href="javascript:void(0);" class="sms-captcha" title="發送驗證碼">獲取短信驗證碼</a>
</div>
<div class="form-item">
<input type="submit" value="立即註冊" class="register-btn">
</div>
</form>
</div>
</main>
{% endblock main_start %}
{% block script %}
<script src="{% static 'js/user/register.js' %}"></script>
{% endblock script %}
4.前端js代碼
注意:在前端頁面中我們引入了一個message.js 用來進行前端頁面提示功能。
user/register.js代碼:
$(function () {
// 定義狀態變量
let isUsernameReady = false,
isPasswordReady = false,
isMobileReady = false,
isSmsCodeReady = false;
// 1.點擊刷新圖像驗證碼
let $img = $('.form-contain .form-item .captcha-graph-img img');
$img.click(function () {
$img.attr('src', '/image_code/?rand=' + Math.random())
});
// 2.鼠標離開用戶名輸入框校驗用戶名
let $username = $('#username');
$username.blur(fnCheckUsername);
function fnCheckUsername () {
isUsernameReady = 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) {
if(data.data.count !== 0){
message.showError(data.data.username + '已經註冊,請重新輸入!')
}else {
message.showInfo(data.data.username + '可以正常使用!')
//用戶名校驗成功,此時isUsernameReady應該改爲true
isUsernameReady = true
}
},
error: function (xhr, msg) {
message.showError('服務器超時,請重試!')
}
});
}
// 3.檢測密碼是否一致
let $passwordRepeat = $('input[name="password_repeat"]');
$passwordRepeat.blur(fnCheckPassword);
function fnCheckPassword () {
isPasswordReady = 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
}
}
三、判斷手機號碼是否註冊功能
1.接口設計
接口說明:
類目 | 說明 |
---|---|
請求方法 | GET |
url定義 | `/mobile/(?P\1[3-9]\d{9})/ |
參數格式 | url路徑參數 |
`參數說明:
參數名 | 類型 | 是否必須 | 描述 |
---|---|---|---|
moblie | 字符串 | 是 | 輸入的手機號碼 |
返回結果:
{
"errno": "0",
"errmsg": "OK",
"data": {
"mobile": "13xxxxxxxxx", # 查詢的手機號
"count": 1 # 手機號查詢的數量
}
}
2.後端代碼
- verification/views.py代碼
# ····
def check_mobile_view(request, mobile):
"""
校驗手機號是否存在
url:/moblie/(?P<moblie>1[3-9]\d{9})/
:param request:
:param username:
:return:
"""
data = {
'mobile': mobile,
'count': User.objects.filter(mobile=mobile).count()
}
return json_response(data=data)
- verification/urls.py
from django.urls import path, re_path
from . import views
# url的命名空間
app_name = 'verification'
urlpatterns = [
path('image_code/', views.image_code_view, name='image_code'),
re_path('username/(?P<username>\w{5,20})/', views.check_username_view, name='check_username'),
re_path('mobile/(?P<mobile>1[3-9]\d{9})/', views.check_mobile_view, name='check_mobile'),
]
- 前端js代碼
$(function () {
// 定義狀態變量
let isUsernameReady = false,
isPasswordReady = false,
isMobileReady = false,
isSmsCodeReady = false;
// 1.點擊刷新圖像驗證碼
let $img = $('.form-contain .form-item .captcha-graph-img img');
$img.click(function () {
$img.attr('src', '/image_code/?rand=' + Math.random())
});
// 2.鼠標離開用戶名輸入框校驗用戶名
let $username = $('#username');
$username.blur(fnCheckUsername);
function fnCheckUsername () {
isUsernameReady = 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) {
if(data.data.count !== 0){
message.showError(data.data.username + '已經註冊,請重新輸入!')
}else {
message.showInfo(data.data.username + '可以正常使用!')
isUsernameReady = true
}
},
error: function (xhr, msg) {
message.showError('服務器超時,請重試!')
}
});
}
// 3.檢測密碼是否一致
let $passwordRepeat = $('input[name="password_repeat"]');
$passwordRepeat.blur(fnCheckPassword);
function fnCheckPassword () {
isPasswordReady = 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"]');
$mobile.blur(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('服務器超時,請重試!')
}
});
}
});