Django項目: 4.用戶登錄登出功能


用戶登錄登出功能

一、功能需求分析

1. 登錄退出功能分析

  1. 流程圖

     

     

     

     

  2. 功能

    1. 登錄頁面

    2. 登錄功能

    3. 退出功能

二、登錄頁面

1. 接口設計

  1. 接口說明

    類目 說明
    請求方法 GET
    url定義 /user/login/
    參數格式 無參數
  2. 返回結果

    登錄頁面

2.后端代碼

  1. user/views.py代碼:

    from django.shortcuts import render
    from django.views import View
    # ....
    
    class LoginView(View):
        """
        登錄視圖
        """
        def get(self, request):
            return render(request, 'user/login.html')

     

  2. user/urls.py代碼:
    from django.urls import path, include
    from . import views
    app_name = 'user'
    
    urlpatterns = [
        path('register/', views.RegisterView.as_view(), name='register'),
        path('login/', views.LoginView.as_view(), name='login'),
    ]

     

3.前端頁面代碼

1.user/login.html

因為表單需要post請求,所以記得在頁面使用{% csrf_token %}標簽。

注冊功能已經開發好了,所以頁面的上的立即注冊處的a標簽href可以寫好

{% 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 %}
    <!-- container start -->
<main id="container">
  <div class="login-contain">
    <div class="top-contain">
      <h4 class="please-login">請登錄</h4>
      <a href="{% url 'user:register' %}" class="register">立即注冊 &gt;</a>
    </div>
    <form action="" method="post" class="form-contain">
      <div class="form-item">
        <input type="tel" placeholder="請輸入用戶名或手機號" name="account" class="form-control" autocomplete="off">
      </div>
      <div class="form-item">
        <input type="password" placeholder="請輸入密碼" name="password" class="form-control">
      </div>
      <div class="form-item clearfix">
        <label>
          <input type="checkbox" name="remember">
          <span>記住我</span>
        </label>
        <a href="javascript:void(0);" class="forget-password">忘記密碼?</a>
      </div>
      <div class="form-login">
        <input type="submit" value="登錄" class="login-btn">
      </div>
        {% csrf_token %}
    </form>
  </div>
</main>
<!-- container end -->
{% endblock main_start %}

 

三、登錄功能

1. 業務流程

  1. 判斷用戶名賬號是否為空

  2. 判斷密碼是否為空,格式是否正確

  3. 判斷賬戶與密碼是否正確

2.接口設計

接口說明:

類目 說明
請求方法 POST
url定義 /user/login/
參數格式 表單參數

參數說明:

參數名 類型 是否必須 描述
account 字符串 用戶輸入的用戶名
password 字符串 用戶輸入的密碼
remember 字符串 用戶是否選擇免登錄

返回結果:

{
    "errno": "0", 
     "errmsg": "OK", 
}

3.后端代碼

  1. 視圖 在user目錄下的views.py文件中定義如下視圖:

    class LoginView(View):
        """
        登錄視圖
        """
        def get(self, request):
            return render(request, 'user/login.html')
    
        def post(self, request):
            form = LoginForm(data=request.POST, request=request)
    
            if form.is_valid():
                return json_response(errmsg='恭喜登錄成功!')
            else:
                err_msg_list = []
                for item in form.errors.values():
                    err_msg_list.append(item[0])
                err_msg_str = '/'.join(err_msg_list)
    
                return json_response(errno=Code.PARAMERR, errmsg=err_msg_str)

     

  2. 表單 在user目下的forms.py文件中定義如下表單:
    class LoginForm(forms.Form):
        account = forms.CharField(error_messages={'required': '賬戶不能為空'})
        password = forms.CharField(max_length=20, min_length=6,
                                   error_messages={
                                       'max_length': '密碼長度要小於20',
                                       'min_length': '密碼長度要大於6',
                                       'require': '密碼不能為空'
                                   })
        remember = forms.BooleanField(required=False)
    
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            super().__init__(*args, **kwargs)
    
        def clean_account(self):
            """
            校驗用戶賬戶
            :return:
            """
            account = self.cleaned_data.get('account')
            if not re.match(r'^1[3-9]\d{9}$', account) and (len(account)<5 or len(account)>20):
                raise forms.ValidationError('用戶賬戶格式不正確,請重新輸入')
            # 一定要return
            return account
    
        def clean(self):
            """
            校驗用戶名密碼,並實現登錄邏輯
            :return:
            """
            cleaned_data = super().clean()
            account = cleaned_data.get('account')
            password = cleaned_data.get('password')
            remember = cleaned_data.get('remember')
    
            # 登錄邏輯
            user_queryset = User.objects.filter(Q(mobile=account)|Q(username=account))
            if user_queryset:
                user = user_queryset.first()
                if user.check_password(password):
                    if remember:
                        self.request.session.set_expiry(constants.USER_SESSION_EXPIRY)
                    else:
                        self.request.session.set_expiry(0)
                    login(self.request, user)
    
                else:
                    raise forms.ValidationError('用戶名密碼錯誤!')
            else:
                raise forms.ValidationError('用戶賬號不存在,請重新輸入!')

    在user文件加下創建constants.py文件定義如下常量

    # 用戶session信息過期時間 單位秒 默認14天
    USER_SESSION_EXPIRY = 14*24*60*60

     

4.前端js代碼

修改user/login.html中用戶賬戶輸入框input的name為account

在static/js/user/下創建login.js文件

js代碼如下:

$(function () {
    let $loginBtn = $('.login-btn');    // 獲取登錄按鈕元素
    $loginBtn.click(function (e) {
        e.preventDefault(); // 阻止默認提交
        // 1.校驗賬戶
        let sAccount = $('input[name="account"]').val();
        if (sAccount === ''){
            message.showError('用戶賬戶不能為空');
            return
        }
        if(!(/^\w{5,20}$/).test(sAccount) && !(/^1[3-9]\d{9}$/).test(sAccount)){
            message.showError('用戶賬戶格式不正確,請求重新輸入');
            return
        }
        // 2.校驗用戶輸入密碼
        let sPassword = $('input[name="password"]').val();
        if(sPassword === ''){
            message.showError('用戶密碼不能為空');
            return
        }
        // 3.獲取用戶是否勾選'記住我',勾選為true,否則為false
        let bRemember = $('input[name="remember"]').is(':checked');
        // 4.發送ajax
        $.ajax({
            url: '/user/login/',
            data: {
                account: sAccount,
                password: sPassword,
                remember: bRemember
            },
            type: 'POST',
            dataType: 'json',
            success: function (res) {
                if(res.errno === '0'){
                    message.showSuccess('恭喜, 登錄成功!');
                    setTimeout(function () {
                        //注冊成功之后重定向到打開登錄頁面之前的頁面
                        if(!document.referrer || document.referrer.includes('/user/login/') || document.referrer.includes('/user/register/')){
                            window.location.href = '/'
                        }else {
                            window.location.href = document.referrer
                        }
                    }, 3000)
                }else{
                    message.showError(res.errmsg)
                }
            },
            error: function (xhr, msg) {
                message.showError('服務器超時,請重試')

            }
        });
    });
});

四、登出功能

1.接口設計

接口說明:

類目 說明
請求方法 GET
url定義 /user/logou/
參數格式 無參數

 

2.后端代碼

# 在user目錄下的views.py文件中定義如下視圖:
class LogoutView(View):
    """
    登出視圖
    """
    def get(self, request):
        logout(request)
        
        return redirect(reverse('user:login'))
# 在urser目錄下的urls.py文件定義如下路由:
from django.urls import path
from . import views
app_name = 'user'

urlpatterns = [
    path('register/', views.RegisterView.as_view(), name='register'),
    path('login/', views.LoginView.as_view(), name='login'),
    path('logout/', views.LogoutView.as_view(), name='logout'),
]

3.前端代碼

# 修改templates/base/base.html中的header部分的代碼如下
<header id="header">
  <div class="mw1200 header-contain clearfix">
    <!-- logo start -->
    <h1 class="logo">
      <a href="javascript:void(0);" class="logo-title">Python</a>
    </h1>
    <!-- logo end -->
    <!-- nav start -->
    <nav class="nav">
      <ul class="menu">
        <li class="active"><a href="base.html">首頁</a></li>
        <li><a href="../course/course.html">在線課堂</a></li>
        <li><a href="../doc/docDownload.html">下載文檔</a></li>
        <li><a href="search.html">搜索</a></li>
      </ul>
    </nav>
    <!-- nav end -->
    <!-- login start -->
      <div class="login-box">
          {% if user.is_authenticated %}
            <div class="author">
              <i class="PyWhich py-user"></i>
              <span>{{ user.username }}</span>
              <ul class="author-menu">
                  {% if user.is_staff %}
                  <li><a href="javascript:void(0);">后台管理</a></li>
                  {% endif %}
                  <li><a href="{% url 'user:logout' %}">退出登錄</a></li>
              </ul>
            </div>
          {% else %}
            <div>
              <i class="PyWhich py-user"></i>
              <span>
                  <a href="{% url 'user:login' %}" class="login">登錄</a> / <a href="{% url 'user:register' %}"
                                                                          class="reg">注冊</a>
              </span>
            </div>
          {% endif %}


      </div>
    <!-- login end -->
  </div>
</header>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM