[Django] Development Daily _8_Day: Mobile Number Management System (6)

1. Implement user login
(0) Supplement of knowledge points

insert image description here
insert image description here

(1) Build a page
思路:url->views->html

urls.py

path('login/', account.login),

views->account.py

from django.shortcuts import render
def login(request):
    """登录"""

    return render(request,'login.html')

login.html

{
    
    % load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .account{
    
    
            width: 400px;
            border: 1px solid #dddddd;
            border-radius: 5px;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }
        .account h2{
    
    
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="account">
        <h2>用户登录</h2>
        <form>
            <div class="form-group">
                <label>用户名</label>
                <input type="text" class="form-control" id="exampleInputEmail1" placeholder="用户名">
            </div>
            <div class="form-group">
                <label>用户名</label>
                <input type="password" class="form-control" placeholder="密码">
            </div>

            <input type="submit" value="登录" class="btn btn-primary">
        </form>


    </div>
</body>
</html>

access effect
insert image description here

(2) Realize identity verification

Modify the style class to inherit BootStrap.py

from django import forms

class BootStrap:
    def __init__(self, *args, **kwargs):
        # 引用父类的ini方法
        super().__init__(*args, **kwargs)
        #循环ModelForm中的字段,给每个字段的插件设置
        for name, field in self.fields.items():
            #字段中有属性,保留原来属性,没有属性增加属性
            if field.widget.attrs:
                field.widget.attrs["class"] = "form-control"
                field.widget.attrs["placeholder"] = field.label
            else:
                field.widget.attrs = {
    
    
                    "class":"form-control",
                    "placeholder":field.label
                }

class BootStrapModelForm(BootStrap,forms.ModelForm):
    pass

class BootStrapForm(BootStrap,forms.Form):
    pass

Use form component form.py

class LoginForm(BootStrapForm):#采用继承
    username = forms.CharField(
        label="用户名",
        widget=forms.TextInput,#(attrs={'class':"form-control",'placeholder':'用户名'})
        required=True
    )
    password = forms.CharField(
        label="密码",
        widget=forms.PasswordInput(render_value=True),#render_value=True:保留原来字段#(attrs={'class':"form-control",'placeholder':'密码'})
        required=True
    )
    def clean_password(self):
        pwd = self.cleaned_data.get("password")
        return md5(pwd)

# class LoginModelForm(forms.ModelForm):
#     class Meta:
#         model = models.Admin
#         fields = ["username",'password']

view function, account.py

from django.shortcuts import render,HttpResponse,redirect
from app01.utils.form import LoginForm
from app01 import models

def login(request):
    """登录"""
    if request.method == "GET":
        form = LoginForm()
        return render(request,'login.html',{
    
    'form':form})

    form = LoginForm(data = request.POST)
    if form.is_valid():
        #print(form.cleaned_data)
        #{'username': '111', 'password': '111'}
        #{'username': '111', 'password': '70a53ebb8836a4400fe2827ab6cc86bf'}
        #去数据库进行校验,获取用户对象、None
        #admin_object = models.Admin.objects.filter(username=form.cleaned_data['username'],password=form.cleaned_data['password']).first()
        admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
        #用户名为空
        if not admin_object:
            form.add_error("password","用户名或密码错误")
            return render(request, 'login.html', {
    
    'form': form})
        #用户名和密码正确
        #网站随机生成字符串,写到用户浏览器的cookie中,在写入到session中
        request.session["info"] = {
    
    'id':admin_object.id,'name':admin_object.username}
        return redirect("/admin/list/")
    return render(request,'login.html',{
    
    'form':form})

login.html

{
    
    % load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
    <style>
        .account{
    
    
            width: 400px;
            border: 1px solid #dddddd;
            border-radius: 5px;
            box-shadow: 5px 5px 20px #aaa;

            margin-left: auto;
            margin-right: auto;
            margin-top: 100px;
            padding: 20px 40px;
        }
        .account h2{
    
    
            margin-top: 10px;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="account">
        <h2>用户登录</h2>
        <form method="post" novalidate><!--novalidate:开启前端校验-->
            {
    
    % csrf_token %}
            <div class="form-group">
                <label>用户名</label>
                {
    
    {
    
     form.username }}
                <span style="color: red">{
    
    {
    
     form.username.errors.0 }}</span>
            </div>
            <div class="form-group">
                <label>用户名</label>
                {
    
    {
    
    form.password}}
                <span style="color: red">{
    
    {
    
     form.password.errors.0 }}</span>
            </div>

            <input type="submit" value="登录" class="btn btn-primary">
        </form>


    </div>
</body>
</html>

visit page
insert image description here
insert image description here

(3) Middleware processing

Authenticate each page (whether you are logged in, you cannot access other pages of the website without logging in)
insert image description here
insert image description here
Graphical middleware
insert image description here

(4) Create middleware samples

Create new directories and files

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render

class M1(MiddlewareMixin):
    """中间件1"""
    def process_request(self,request):
        #没有返回值,返回None,继续向后走
        #有返回值 HttpResponse
        print("M1.进来了")
        #return HttpResponse("无权访问")
        #return render()
        #return redirect()
        

    def process_response(self,request,response):
        print("M1.走了")
        return response

class M2(MiddlewareMixin):
    """中间件2"""
    def process_request(self,request):
        print("M2.进来了")

    def process_response(self,request,response):
        print("M2.走了")
        return response

Modify setting.py to register middleware

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'app01.middleware.auth.M1',
    'app01.middleware.auth.M2',
]

Next, when you visit the page, you will find that each visit will call the middleware,
insert image description here
which is in line with this process.
insert image description here
insert image description here

(5) Login authentication based on middleware

Write middleware
auth.py

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse,redirect,render

class AuthMiddleware(MiddlewareMixin):
    """中间件"""
    def process_request(self,request):
        #0、排除不需要登录验证就能访问的页面
        if request.path_info == "/login/":
            return
        #1、读取当前访问的用户的session信息,如果能读到,说明已登录过,就可以继续向后走
        info_dict = request.session.get("info")
        if info_dict:
            return
        # 2、没登录过,重新登录
        return redirect("/login/")

Application middleware
setting.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'app01.middleware.auth.AuthMiddleware',
]

Access page:
If you are not logged in, you can only see the login interface
insert image description here

(6) Implement user logout function

Logout: To put it bluntly, it is to clear the session data in the browser cookie.
insert image description here
Implementation method
urls,py

path('logout/', account.logout),

account.py

def logout(request):
    """注销"""
    request.session.clear()
    return redirect("/login/")

Modify the template, add links and display nicknames
insert image description here
template.py

{
    
    % load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>
        {
    
    % block title_content %}
        {
    
    % endblock %}
    </title>
    <link rel="stylesheet" href="{% static 'plugins/bootstrap-3.4.1/css/bootstrap.min.css' %}">
</head>
<body>
<!--导航-->
<div class="bs-example" data-example-id="inverted-navbar">
    <nav class="navbar navbar-inverse">
        <div class="container">
            <!-- Brand and toggle get grouped for better mobile display -->
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                        data-target="#bs-example-navbar-collapse-9" aria-expanded="false">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/pretty/list/">靓号管理系统</a>
            </div>

            <!-- Collect the nav links, forms, and other content for toggling -->
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-9">
                <ul class="nav navbar-nav">
                    <li><a href="/admin/list/">管理员账户</a></li>
                    <li><a href="/depart/list/">部门管理</a></li>
                    <li><a href="/user/list/">用户管理</a></li>
                    <li><a href="/pretty/list/">靓号管理</a></li>

                </ul>
                <ul class="nav navbar-nav navbar-right">
                    <li><a href="/login/">登录</a></li>
                    <li class="dropdown">
                        <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
                           aria-expanded="false">{
    
    {
    
     request.session.info.name }} <span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="#">个人资料</a></li>
                            <li><a href="#">我的信息</a></li>
                            <li role="separator" class="divider"></li>
                            <li><a href="/logout/">注销</a></li>
                        </ul>
                    </li>
                </ul>
            </div><!-- /.navbar-collapse -->

        </div><!-- /.container-fluid -->
    </nav>
</div>

{
    
    % block content %}{
    
    % endblock %}

<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'plugins/bootstrap-3.4.1/js/bootstrap.min.js' %}"></script>
</body>
</html>

Log in to the website
insert image description here
to log out and display the user's nickname
insert image description here

Guess you like

Origin blog.csdn.net/qq_51701007/article/details/127056934