User login and logout function

I. Functional Requirement Analysis

1. Login and Exit Function Analysis

  1. Flow chart

     

     

     

     

  2. function

    1. Login page

    2. Login function

    3. Exit function

II. Login Page

1. Interface design

  1. Interface specification

    Category Explain
    Request method GET
    url definition /user/login/
    Parameter format No parameter
  2. Return result

    Login page

2. Backend code

  1. user/views.py code:

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

     

  2. user/urls.py code:
    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. Front-end page code

1.user/login.html

Because the form requires a post request, remember to use the {% csrf_token%} tag on the page.

The registration function has been developed, so the a tag href of the immediate registry on the page can be written.

{% extends 'base/base.html' %}
{% load static %}

{% block title %}Sign in{% 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">Please login</h4>
      <a href="{% url 'user:register' %}" class="register">Immediate registration &gt;</a>
    </div>
    <form action="" method="post" class="form-contain">
      <div class="form-item">
        <input type="tel" placeholder="Please enter your username or mobile phone number." name="account" class="form-control" autocomplete="off">
      </div>
      <div class="form-item">
        <input type="password" placeholder="Please input a password" name="password" class="form-control">
      </div>
      <div class="form-item clearfix">
        <label>
          <input type="checkbox" name="remember">
          <span>Remember me</span>
        </label>
        <a href="javascript:void(0);" class="forget-password">Forget password?</a>
      </div>
      <div class="form-login">
        <input type="submit" value="Sign in" class="login-btn">
      </div>
        {% csrf_token %}
    </form>
  </div>
</main>
<!-- container end -->
{% endblock main_start %}

 

III. Login Function

1. Business processes

  1. Determine whether the username account is empty

  2. Determine whether the password is empty and the format is correct

  3. Determine whether the account and password are correct

2. Interface design

Interface Description:

Category Explain
Request method POST
url definition /user/login/
Parameter format Form parameter

Description of parameters:

Parameter name type Is it necessary? describe
account Character string yes User Name Input
password Character string yes Password entered by user
remember Character string no Whether the user chooses to log-in-free

Returns the result:

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

3. Backend code

  1. Views are defined in the views.py file in the user directory as follows:

    class LoginView(View):
        """
        //Login 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='Congratulations on your successful login!')
            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. The form is defined in the forms.py file under user heading as follows:
    class LoginForm(forms.Form):
        account = forms.CharField(error_messages={'required': 'Account cannot be empty'})
        password = forms.CharField(max_length=20, min_length=6,
                                   error_messages={
                                       'max_length': 'Password length should be less than 20',
                                       'min_length': 'Password length greater than 6',
                                       'require': 'Password cannot be empty'
                                   })
        remember = forms.BooleanField(required=False)
    
        def __init__(self, *args, **kwargs):
            self.request = kwargs.pop('request', None)
            super().__init__(*args, **kwargs)
    
        def clean_account(self):
            """
            //Verify user accounts
            :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('User account format is incorrect, please re-enter')
            # Must do return
            return account
    
        def clean(self):
            """
            //Verify username password and implement login logic
            :return:
            """
            cleaned_data = super().clean()
            account = cleaned_data.get('account')
            password = cleaned_data.get('password')
            remember = cleaned_data.get('remember')
    
            # Logon logic
            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('User name password error!')
            else:
                raise forms.ValidationError('User account does not exist, please re-enter!')

    Create constants.py file under user file to define the following constants

    # user session Information expiration time defaults to 14 days per second
    USER_SESSION_EXPIRY = 14*24*60*60

     

4. Front-end js code

Modify the name of the user account input box in user/login.html to account.

Create login.js file under static/js/user/.

The js code is as follows:

$(function () {
    let $loginBtn = $('.login-btn');    // Get the login button element
    $loginBtn.click(function (e) {
        e.preventDefault(); // Prevent default submission
        // 1.Checking account
        let sAccount = $('input[name="account"]').val();
        if (sAccount === ''){
            message.showError('User account cannot be empty');
            return
        }
        if(!(/^\w{5,20}$/).test(sAccount) && !(/^1[3-9]\d{9}$/).test(sAccount)){
            message.showError('User account format incorrect, request re-entry');
            return
        }
        // 2.Verify user input password
        let sPassword = $('input[name="password"]').val();
        if(sPassword === ''){
            message.showError('User password cannot be empty');
            return
        }
        // 3.Get whether the user checks'Remember me',Choose as true,Otherwise, false
        let bRemember = $('input[name="remember"]').is(':checked');
        // 4.Send out 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('Congratulations, login success!');
                    setTimeout(function () {
                        //After successful registration, redirect to the page before opening the login page
                        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('Server timeout, please try again')

            }
        });
    });
});

IV. Logout function

1. Interface design

Interface Description:

Category Explain
Request method GET
url definition /user/logou/
Parameter format No parameter

 

2. Backend code

# stay user Directory views.py The following views are defined in the file:
class LogoutView(View):
    """
    //Logout view
    """
    def get(self, request):
        logout(request)
        
        return redirect(reverse('user:login'))
# stay urser Directory urls.py The file defines the following routing:
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. Front-end code

# The code to modify the header section in templates/base/base.html is as follows
<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">home page</a></li>
        <li><a href="../course/course.html">Online classroom</a></li>
        <li><a href="../doc/docDownload.html">Download documents</a></li>
        <li><a href="search.html">search</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);">Back-stage management</a></li>
                  {% endif %}
                  <li><a href="{% url 'user:logout' %}">Logout</a></li>
              </ul>
            </div>
          {% else %}
            <div>
              <i class="PyWhich py-user"></i>
              <span>
                  <a href="{% url 'user:login' %}" class="login">Sign in</a> / <a href="{% url 'user:register' %}"
                                                                          class="reg">register</a>
              </span>
            </div>
          {% endif %}


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