天天看點

django實戰商城項目注冊業務實作

django實戰商城項目注冊業務實作

設計到的前端知識

項目的前端頁面使用vue來實作局部重新整理,通過資料的雙向綁定實作與使用者的互動,下面來看一下需求,在使用者輸入内容後,前端需要做一些簡單的規則校驗,我們希望在在使用者輸入後能夠實時檢測,如果有錯誤能夠在輸入框的下方顯示出來。

<label>使用者名:</label>
<input type="text" name="username" id="user_name">
<span class="error_tip">請輸入5-20個字元的使用者</span>           
<label>密碼:</label>
<input type="password" name="password" id="pwd">
<span class="error_tip">請輸入8-20位的密碼</span>           

上面是一個使用者和密碼的輸入框,當使用者輸入完使用者名以後,光标離開輸入框,能夠實時的檢測輸入内容的正确性,當輸入有問題的時候,在輸入框的下方顯示錯誤資訊。

v-model實作資料的雙向綁定,v-on進行事件綁定,v-show是控制dom顯示與否,下面是加入vue後的部分代碼

<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>           
<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>           

使用者輸入的使用者名和username變量綁定,光标消失觸發綁定時間check_username,通過v-show綁定到布爾值變量error_name,來控制是否顯示字元串變量error_name_message,其他的輸入框都類似這種操作。

注冊業務實作

前端注冊業務邏輯

系統資料庫單代碼:

{{ 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>           

導入vue.js和ajax請求的js庫

準備register.js檔案

register.js檔案主要處理注冊頁面的互動事件,并且向服務端送出系統資料庫單請求

下面是實作的前端校驗邏輯以及表單送出邏輯

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/', views.UsernameCountView.as_view(), name="username"),

re_path(r'mobiles/(?P1[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"

原文位址

https://www.cnblogs.com/zyjimmortalp/p/12464883.html