設計到的前端知識
專案的前端頁面使用vue來實現區域性重新整理,通過資料的雙向繫結實現與使用者的互動,下面來看一下需求,在使用者輸入內容後,前端需要做一些簡單的規則校驗,我們希望在在使用者輸入後能夠實時檢測,如果有錯誤能夠在輸入框的下方顯示出來。
<li>
<label>使用者名稱:</label>
<input type="text" name="username" id="user_name">
<span class="error_tip">請輸入5-20個字元的使用者</span>
</li>
<li>
<label>密碼:</label>
<input type="password" name="password" id="pwd">
<span class="error_tip">請輸入8-20位的密碼</span>
</li>
上面是一個使用者和密碼的輸入框,當用戶輸入完使用者名稱以後,游標離開輸入框,能夠實時的檢測輸入內容的正確性,當輸入有問題的時候,在輸入框的下方顯示錯誤資訊。
v-model實現資料的雙向繫結,v-on進行事件繫結,v-show是控制dom顯示與否,下面是加入vue後的部分程式碼
<li>
<label>使用者名稱:</label>
<input type="text" name="username" id="user_name" v-model="username" @blur="check_username">
<span class="error_tip" v-show="error_name">[[error_name_message]]</span>
</li>
<li>
<label>密碼:</label>
<input type="password" name="password" id="pwd" v-model="password" @blur="check_password">
<span class="error_tip" v-show="error_password">請輸入8-20位的密碼</span>
</li>
使用者輸入的使用者名稱和username變數繫結,游標消失觸發繫結時間check_username,通過v-show繫結到布林值變數error_name,來控制是否顯示字串變數error_name_message,其他的輸入框都類似這種操作。
註冊業務實現
前端註冊業務邏輯
登錄檔單程式碼:
<form method="post" class="register_form" >
{{ csrf_input }}
<ul>
<li>
<label>使用者名稱:</label>
<input type="text" name="username" id="user_name" v-model="username" @blur="check_username">
<span class="error_tip" v-show="error_name">[[error_name_message]]</span>
</li>
<li>
<label>密碼:</label>
<input type="password" name="password" id="pwd" v-model="password" @blur="check_password">
<span class="error_tip" v-show="error_password">請輸入8-20位的密碼</span>
</li>
<li>
<label>確認密碼:</label>
<input type="password" v-model="password2" @blur="check_password2" name="password2"
id="cpwd">
<span class="error_tip" v-show="error_password2">兩次輸入的密碼不一致</span>
</li>
<li>
<label>手機號:</label>
<input type="text" v-model="mobile" @blur="check_mobile" name="mobile" id="phone">
<span class="error_tip" v-show="error_mobile">[[ error_mobile_message ]]</span>
</li>
<li>
<label>圖形驗證碼:</label>
<input type="text" name="image_code" id="pic_code" class="msg_input">
<img src="{{ static('images/pic_code.jpg') }}" alt="圖形驗證碼" class="pic_code">
<span class="error_tip">請填寫圖形驗證碼</span>
</li>
<li>
<label>簡訊驗證碼:</label>
<input type="text" name="sms_code" id="msg_code" class="msg_input">
<a href="javascript:;" class="get_msg_code">獲取簡訊驗證碼</a>
<span class="error_tip">請填寫簡訊驗證碼</span>
</li>
<li class="agreement">
<input type="checkbox" name="allow" id="allow" v-model="allow" @change="check_allow">
<label>同意”商城使用者使用協議“</label>
<span class="error_tip" v-show="error_allow">請勾選使用者協議</span>
</li>
<li class="reg_sub">
<input type="submit" value="注 冊" @change="on_submit">
{% if register_errmsg %}
<span class="error_tip2">{{ register_errmsg }}</span>
{% endif %}
</li>
</ul>
</form>
匯入vue.js和ajax請求的js庫
<script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script>
<script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>
準備register.js檔案
register.js檔案主要處理註冊頁面的互動事件,並且向服務端提交登錄檔單請求
<script type="text/javascript" src="{{ static('js/register.js') }}"></script>
下面是實現的前端校驗邏輯以及表單提交邏輯
methods: {
// 校驗使用者名稱
check_username() {
let re = /^[a-zA-Z0-9_-]{5,20}$/;
if (re.test(this.username)) {
this.error_name = false;
} else {
this.error_name_message = '請輸入5-20個字元的使用者名稱';
this.error_name = true;
}
},
// 校驗密碼
check_password() {
let re = /^[0-9A-Za-z]{8,20}$/;
this.error_password = !re.test(this.password);
},
// 校驗確認密碼
check_password2() {
if (this.password !== this.password2) {
this.error_password2 = true;
} else {
this.error_password2 = false;
}
},
// 校驗手機號
check_mobile() {
let re = /^1[3-9]\d{9}$/;
if (re.test(this.mobile)) {
this.error_mobile = false;
} else {
this.error_mobile_message = '您輸入的手機號格式不正確';
this.error_mobile = true;
}
},
// 校驗是否勾選協議
check_allow() {
this.error_allow = !this.allow;
},
// 監聽表單提交事件
on_submit() {
this.check_username();
this.check_password();
this.check_password2();
this.check_mobile();
this.check_allow();
# 輸入欄位中有一個不符合規則就禁止
if (this.error_name === true || this.error_password === true || this.error_password2 === true
|| this.error_mobile === true || this.error_allow === true) {
// 禁用表單的提交
window.event.returnValue = false;
}
},
}
後端業務註冊邏輯
在使用者輸完使用者名稱之後,我們往往希望能夠跟快的給出這個使用者名稱是否符合註冊需求,前面只是對使用者名稱的規則進行了校驗,還想知道他是否已經在系統註冊過了,不然當用戶都輸完提交註冊再給出使用者名稱或者手機號已經註冊過,體驗不是特別好。所以需要在游標離開使用者名稱輸入框的時候就請求服務端來判斷是否註冊過。
定義路由
path('register/', views.RegisterView.as_view(), name='register'), # name新增名稱空間
path('usernames/<str:username>', views.UsernameCountView.as_view(), name="username"),
re_path(r'mobiles/(?P<mobile>1[3-9]\d{9})', views.MobileCountView.as_view(), name='mobile')
編寫檢視類
class UsernameCountView(View):
def get(self, request, username):
"""
查詢該使用者名稱是否在系統中存在
:param request: 請求對像
:param username: 前端傳遞的使用者名稱
:return:
"""
count = User.objects.filter(username=username).count()
return http.JsonResponse({'code':1001, 'msg':'使用者已存在'}) if count == 1 \
else http.JsonResponse({'code': 1000, 'msg': ''})
這裡沒有對響應做統一處理封裝,後面專門介紹一下。
然後就是註冊檢視類的編寫了:
class RegisterView(View):
"""使用者註冊檢視類"""
def get(self, request):
'''獲取註冊頁面'''
return render(request, 'register.html')
def post(self, request):
""""""
username = request.POST.get('username')
password = request.POST.get('password')
password2 = request.POST.get('password2')
mobile = request.POST.get('mobile')
allow = request.POST.get('allow')
# 判斷引數是否齊全
if not all([username, password, password2, mobile, allow]):
return http.HttpResponseForbidden('缺少必傳引數')
# 判斷使用者名稱是否是5-20個字元
if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
return http.HttpResponseForbidden('請輸入5-20個字元的使用者名稱')
# 判斷密碼是否是8-20個數字
if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
return http.HttpResponseForbidden('請輸入8-20位的密碼')
# 判斷兩次密碼是否一致
if password != password2:
return http.HttpResponseForbidden('兩次輸入的密碼不一致')
# 判斷手機號是否合法
if not re.match(r'^1[3-9]\d{9}$', mobile):
return http.HttpResponseForbidden('請輸入正確的手機號碼')
# 判斷是否勾選使用者協議
if allow != 'on':
return http.HttpResponseForbidden('請勾選使用者協議')
try:
user = User.objects.create_user(username=username, password=password, mobile=mobile)
except DatabaseError as e:
return render(request, 'register.html', {'register_errmsg': e.args})
# 註冊成功儲存會話
login(request, user)
return redirect(reverse('contents:index'))
django提供的login方法,封裝了寫入session的操作,幫助我們快速登入一個使用者,並實現狀態保持,將通過認證的使用者的唯一標識資訊(比如:使用者ID)寫入到當前瀏覽器的 cookie 和服務端的 session 中。
request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = backend
request.session[HASH_SESSION_KEY] = session_auth_hash
session會存入redis,之前在工程建立時進行session儲存的配置
SESSION_ENGINE = "django.contrib.sessions.backends.cache"
SESSION_CACHE_ALIAS = "session"
關注公眾號:測試老憨,回覆:商城,獲取完成專案程式碼