Django_CMDB系统开发 一

Django_CMDB系统开发

一、CMDB相关概念

1、概念介绍

CMDB(配置管理数据库)存储与管理企业IT架构中设备的各种配置信息,它与所有服务支持和服务交付流程都紧密相联,支持这些流程的运转、发挥配置信息的价值,同时依赖于相关流程保证数据的准确性。

服务器集群或者分布式服务器 几十台、上百台,服务器相关数据信息,管理不方便。通过资产管理的方式,通过CMDB系统实现。

github一些开源的cmdb系统:https://github.com/search?q=cmdb

2、需求分析

本次开发的CMDB系统实现以下模块:
--用户管理模块
--用户组管理模块
--权限管理模块
--资产主机模块
--资产机房模块
--资产用户模块

概括一下,本次学习开发的CMDB,是一个收集服务器信息,实现服务器信息可视化,给自动化运维监控提供数据统计和展示等基础服务。

3、设计实现

CMDB使用关系图示:

img

本次开发的CMDB系统结构图示:

在这里插入图片描述

二、创建CMDB项目

1、创建项目

1、使用Pycharm创建Django项目

image-20231014171056293

image-20231014171446201

image-20231014171623130

2、默认初始化配置

配置静态资源目录

创建static文件夹

image-20231014171755513

时区配置

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_TZ = False

settings.py配置

STATIC_URL = 'static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static')
    # BASE_DIR / 'static'
    BASE_DIR / 'static'
]

image-20231014172313372

3、数据库配置

创建数据库

CREATE DATABASE cmdb DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

image-20231015082710127

配置数据库

settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'cmdb',
        'USER': 'root',
        'PASSWORD': 'fxx123',
        'HOST': '10.0.0.131',
        'PORT': '3306',
        'OPTIONS': {
            "init_command": "SET sql_mode='STRICT_TRANS_TABLES'"
        }
    }
}

image-20231015083253726

__init__.py

import pymysql
pymysql.install_as_MySQLdb()

image-20231015082855040

迁移数据库

python manage.py makemigrations   # 生成迁移表
python manage.py migrate           # 进行数据迁移

image-20231015083336921

image-20231015083416859

三、管理后台布局

1、后台前端模板介绍

使用INSPINIA模板,实现管理后台的前端模板页面

image-20231015072943360

2、基础页面布局

先定义一个基础页面,包含各个页面中的公共部分,方便其他页面继承。

部署静态资源

image-20231015083452471

在应用下建立模板目录,方便之后分开管理

image-20231015083608901

定义路由

cmdb\cmdb\urls.py

from django.contrib import admin
from django.urls import path,include
urlpatterns = [
	path('admin/', admin.site.urls),
	path('dashboard/',include('dashboard.urls'))
]

image-20231015074701577

cmdb\dashboard\urls.py

from django.urls import path
from  dashboard.views import *
urlpatterns = [
   path('base/',BaseView.as_view())
]

image-20231014181549491

类视图

from django.shortcuts import render
from django.views.generic import View

class BaseView(View):
	def get(self,request):
		return render(request,'base.html')

image-20231015084031444

模板页面

可以通过模板页面,进行修改。或者直接使用修改好的模板

注意静态资源路径的修改和替换

base.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>CMDB管理系统</title>

    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
    <link href="/static/css/plugins/toastr/toastr.min.css" rel="stylesheet">

    <link href="/static/css/animate.css" rel="stylesheet">
    <link href="/static/css/style.css" rel="stylesheet">
    <link rel="stylesheet" href="/static/css/plugins/sweetalert/sweetalert.css">
    {% block load_css %}
    {% endblock %}

</head>
<body>

<div id="wrapper">

    <nav class="navbar-default navbar-static-side" role="navigation">
        <div class="sidebar-collapse">
            <ul class="nav metismenu" id="side-menu">
                <li class="nav-header">
                    <div class="dropdown profile-element" >
                        <a data-toggle="dropdown" class="dropdown-toggle" href="#">
                            <span class="clear"> <span class="block m-t-xs"> <strong class="font-bold">{{ request.user.username }}</strong>
                             </span> <span class="text-muted text-xs block">{{ request.user.groups.filter.0 }}<b class="caret"></b></span> </span>
                        </a>
                        <ul class="dropdown-menu animated fadeInRight m-t-xs">
                            <li><a href="profile.html">个人信息</a></li>
                        </ul>
                    </div>
                </li>
                <li>
                    <a href="../dashboard/templates/index.html"><i class="fa fa-th-large"></i> <span class="nav-label">系统管理</span> <span
                            class="fa arrow"></span></a>
                </li>
                <li>
                    <a href="#"><i class="fa fa-bar-chart-o"></i> <span class="nav-label">资产管理</span><span
                            class="fa arrow"></span></a>
                </li>
            </ul>

        </div>
    </nav>

    <div id="page-wrapper" class="gray-bg">
        <div class="row border-bottom">
            <nav class="navbar navbar-static-top  " role="navigation" style="margin-bottom: 0">
                <div class="navbar-header">
                    <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i>
                    </a>
                </div>
                <ul class="nav navbar-top-links navbar-right">
                    <li>
                        <span class="m-r-sm text-muted welcome-message">欢迎来到配置数据库管理系统 </span>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </欢迎来到SYSCMDB自动化管理系统></span>
                    </li>
                </ul>

            </nav>
        </div>

        {% block mbx %}
            <div class="row wrapper border-bottom white-bg page-heading">
                <div class="col-sm-4">
                    <h2>仪表盘</h2>
                    <ol class="breadcrumb">
                        <li>
                            <a href="../dashboard/templates/index.html">首页</a>
                        </li>
                    </ol>
                </div>
            </div>
        {% endblock %}

        {% block body %}
            <h1>这是BASE页面</h1>
        {% endblock %}

    </div>

</div>


<!-- Mainly scripts -->
<script src="/static/js/jquery-3.1.1.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>

<!-- Custom and plugin javascript -->
<script src="/static/js/inspinia.js"></script>
<script src="/static/js/plugins/pace/pace.min.js"></script>
<script src="/static/js/plugins/validate/jquery.validate.js"></script>
<script src="/static/js/plugins/validate/messages_zh.js"></script>
<script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
<script>
    function aaa(i){
        console.log(i)
    }

    </script>
{% block load_js %}

{% endblock %}

</body>

</html>

image-20231015084412213

查看效果

http://127.0.0.1:8000/dashboard/base/

image-20231015090330544

以上页面视图和页面,作为测试使用。

3、首页面实现

路由

cmdb/urls.py

RediretView 重定向 URL跳转

from django.contrib import admin
from django.urls import path,include
from django.views.generic import RedirectView

urlpatterns = [
	path('admin/', admin.site.urls),
	path('',RedirectView.as_view(url='dashboard/')),
	path('dashboard/',include('dashboard.urls'))
]

image-20231015090651847

dashboard/urls.py

from django.urls import path
from  dashboard.views import *

urlpatterns = [
   path('base/',BaseView.as_view()),
   path('',IndexView.as_view(),name='index'),
]

image-20231015090929239

视图

dashboard/views.py

from django.shortcuts import render
from django.views.generic import View

class BaseView(View):
	def get(self,request):
		return render(request,'base.html')
# Create your views here.
class IndexView(View):
    def get(self,request):
        return render(request,'index.html')

image-20231015091152318

模板

dashboard/templates/index.html

{% extends 'base.html' %}

{% block body%}
    这是CMDB首页面

{% endblock %}

image-20231015091600056

修改base.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>CMDB管理系统</title>

    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
    <link href="/static/css/plugins/toastr/toastr.min.css" rel="stylesheet">

    <link href="/static/css/animate.css" rel="stylesheet">
    <link href="/static/css/style.css" rel="stylesheet">
    <link rel="stylesheet" href="/static/css/plugins/sweetalert/sweetalert.css">
    {% block load_css %}
    {% endblock %}

</head>
<body>

<div id="wrapper">

    <nav class="navbar-default navbar-static-side" role="navigation">
        <div class="sidebar-collapse">
            <ul class="nav metismenu" id="side-menu">
                <li class="nav-header">
                    <div class="dropdown profile-element" >
                        <a data-toggle="dropdown" class="dropdown-toggle" href="#">
                            <span class="clear"> <span class="block m-t-xs"> <strong class="font-bold">{{ request.user.username }}</strong>
                             </span> <span class="text-muted text-xs block">{{ request.user.groups.filter.0 }}<b class="caret"></b></span> </span>
                        </a>
                        <ul class="dropdown-menu animated fadeInRight m-t-xs">
                            <li><a href="profile.html">个人信息</a></li>
                        </ul>
                    </div>
                </li>
                <li>
                    <a href="{% url 'index' %}"><i class="fa fa-bar-chart-o"></i> <span class="nav-label">首页</span></a>
                </li>
                <li>
                    <a href="../dashboard/templates/index.html"><i class="fa fa-th-large"></i> <span class="nav-label">系统管理</span> <span
                            class="fa arrow"></span></a>
                </li>
                <li>
                    <a href="#"><i class="fa fa-bar-chart-o"></i> <span class="nav-label">资产管理</span><span
                            class="fa arrow"></span></a>
                </li>
            </ul>

        </div>
    </nav>

    <div id="page-wrapper" class="gray-bg">
        <div class="row border-bottom">
            <nav class="navbar navbar-static-top  " role="navigation" style="margin-bottom: 0">
                <div class="navbar-header">
                    <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i>
                    </a>
                </div>
                <ul class="nav navbar-top-links navbar-right">
                    <li>
                        <span class="m-r-sm text-muted welcome-message">欢迎来到配置数据库管理系统 </span>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </欢迎来到SYSCMDB自动化管理系统></span>
                    </li>
                </ul>

            </nav>
        </div>

        {% block mbx %}
            <div class="row wrapper border-bottom white-bg page-heading">
                <div class="col-sm-4">
                    <h2>仪表盘</h2>
                    <ol class="breadcrumb">
                        <li>
                            <a href="../dashboard/templates/index.html">首页</a>
                        </li>
                    </ol>
                </div>
            </div>
        {% endblock %}

        {% block body %}
            <h1>这是BASE页面</h1>
        {% endblock %}

    </div>

</div>


<!-- Mainly scripts -->
<script src="/static/js/jquery-3.1.1.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>

<!-- Custom and plugin javascript -->
<script src="/static/js/inspinia.js"></script>
<script src="/static/js/plugins/pace/pace.min.js"></script>
<script src="/static/js/plugins/validate/jquery.validate.js"></script>
<script src="/static/js/plugins/validate/messages_zh.js"></script>
<script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
<script>
    function aaa(i){
        console.log(i)
    }

    </script>
{% block load_js %}

{% endblock %}

</body>

</html>

查看效果

image-20231015091859661

4、高级视图类之TemplateView

TemplateView,这个类封装了View提供了更强大的功能。

使用TemplateView,加载渲染页面

使用TemplateView

dashboard/views.py

from django.shortcuts import render
from django.views.generic import View, TemplateView

class BaseView(View):
	def get(self,request):
		return render(request,'base.html')
# Create your views here.
# class IndexView(View):
#     def get(self,request):
        # return render(request,'index.html')
class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['name'] = 'DevOps'
        return context

image-20231015092925901

在模板中调用

index.html

{% extends 'base.html' %}

{% block body%}
    这是CMDB首页面
    <p> {{ name }} </p>
{% endblock %}

查看显示效果

image-20231015092957686

四、登录管理

1、登录基本实现

实现完成首页面后,为了能够更加安全,就需要实现一个登录功能,只有登录之后,才能够查看管理后台。

登录页面实现后的效果:

①路由

cmdb/urls.py

from django.contrib import admin
from django.urls import path,include
from django.views.generic import RedirectView
from dashboard.views import *

urlpatterns = [
	path('admin/', admin.site.urls),
	path('',RedirectView.as_view(url='dashboard/')),
	path('login/',LoginView.as_view(),name='login'),
	path('dashboard/',include('dashboard.urls'))
]

image-20231015093315495

视图

dashboard/views.py

from django.shortcuts import render
from django.views.generic import View, TemplateView

class BaseView(View):
	def get(self,request):
		return render(request,'base.html')
# Create your views here.
# class IndexView(View):
#     def get(self,request):
        # return render(request,'index.html')
class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['name'] = 'DevOps'
        return context
class LoginView(TemplateView):
    template_name = 'login.html'

image-20231015093511355

在后端接收用户传输的数据

登录基础原理:前端页面输入账号密码===》后端接收信息参数 ===》类视图判断校验

模板页面通过ajax post请求发送数据

dashboard/templates/login.html

<!DOCTYPE html>
<html>
 
<head>
 
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 
    <title>CMDB系统 | 登录</title>
 
    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
 
    <link href="/static/css/animate.css" rel="stylesheet">
    <link href="/static/css/style.css" rel="stylesheet">
    <link href="/static/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">
 
</head>
 
<body class="gray-bg">
 
<div class="middle-box text-center loginscreen animated fadeInDown">
    <div>
        <div>
 
            <h1 class="logo-name">CMDB</h1>
 
        </div>
        <h3>欢迎登录CMDB系统</h3>
        <p>
        </p>
        <p>快乐游戏,欢乐至上</p>
        <form class="m-t" id="login_form">
            {% csrf_token %}
 
            <div class="form-group">
                <input type="text" class="form-control" placeholder="用户名" name="username">
            </div>
            <div class="form-group">
                <input type="password" class="form-control" placeholder="密码" name="password">
            </div>
            <button type="submit" class="btn btn-primary block full-width m-b">登录</button>
             
 
        </form>
    </div>
</div>
 
<!-- Mainly scripts -->
<script src="/static/js/jquery-3.1.1.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/validate/jquery.validate.js"></script>
<script src="/static/js/plugins/validate/messages_zh.js"></script>
<script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
<script>
 
    $('#login_form').submit( function () {

        var str = $('#login_form').serialize();
            $.post('{% url 'login' %}', str, function (res) {
            if (res.status == 0) {
                alert('登录成功')
            } else {
                alert('登录失败')
            }
            }
            )
    })

</script>

</body>

</html>

image-20231015105837277

后端视图

校验账号和密码并返回数据

Tip:使用返回json数据格式的声明

from django.shortcuts import render
from django.views.generic import View, TemplateView
from django.http import JsonResponse
class BaseView(View):
	def get(self,request):
		return render(request,'base.html')
# Create your views here.
# class IndexView(View):
#     def get(self,request):
        # return render(request,'index.html')
class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['name'] = 'DevOps'
        return context

class LoginView(TemplateView):
    template_name = 'login.html'

    def post(self, request):
        data = request.POST
        # 校验用户和密码
        if data.get('username') == 'admin' and data.get('password') == '123456':
            res = {'status': 0, 'msg': '校验成功'}
 
        else:
            res = {'status': 1, 'msg': '用户名或者密码错误'}
        return JsonResponse(res)

显示效果

image-20231015112047692

image-20231015112105519

美化提示窗口

模板引入sweetaltert js库

image-20231015112359377

实现方式

<!DOCTYPE html>
<html>

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>CMDB系统 | 登录</title>

    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">

    <link href="/static/css/animate.css" rel="stylesheet">
    <link href="/static/css/style.css" rel="stylesheet">
    <link href="/static/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">

</head>

<body class="gray-bg">

<div class="middle-box text-center loginscreen animated fadeInDown">
    <div>
        <div>

            <h1 class="logo-name">CMDB</h1>

        </div>
        <h3>欢迎登录CMDB系统</h3>
        <p>
        </p>
        <p>快乐游戏,欢乐至上</p>
        <form class="m-t" id="login_form">
            {% csrf_token %}

            <div class="form-group">
                <input type="text" class="form-control" placeholder="用户名" name="username">
            </div>
            <div class="form-group">
                <input type="password" class="form-control" placeholder="密码" name="password">
            </div>
            <button type="submit" class="btn btn-primary block full-width m-b">登录</button>


        </form>
    </div>
</div>

<!-- Mainly scripts -->
<script src="/static/js/jquery-3.1.1.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/validate/jquery.validate.js"></script>
<script src="/static/js/plugins/validate/messages_zh.js"></script>
<script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
<script>

    $('#login_form').submit( function () {

        var str = $('#login_form').serialize();
            $.post('{% url 'login' %}', str, function (res) {
            if (res.status == 0) {
                alert('登录成功')
            } else {
               swal({
                   title: '登录失败',
                   type: 'error',
                   confirmButtonText: '知道了'
               });
            }
            }
            )
    });

</script>

</body>

</html>

image-20231015114440103

image-20231015115247334

s表单验证 jquery.validate

引入js文件, jquery.validate 是基于jquery的,所有需要先引入jquery

image-20231015114522518

校验代码

<!DOCTYPE html>
<html>

<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>CMDB系统 | 登录</title>

    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">

    <link href="/static/css/animate.css" rel="stylesheet">
    <link href="/static/css/style.css" rel="stylesheet">
    <link href="/static/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">

</head>

<body class="gray-bg">

<div class="middle-box text-center loginscreen animated fadeInDown">
    <div>
        <div>

            <h1 class="logo-name">CMDB</h1>

        </div>
        <h3>欢迎登录CMDB系统</h3>
        <p>
        </p>
        <p>快乐游戏,欢乐至上</p>
        <form class="m-t" id="login_form">
            {% csrf_token %}

            <div class="form-group">
                <input type="text" class="form-control" placeholder="用户名" name="username">
            </div>
            <div class="form-group">
                <input type="password" class="form-control" placeholder="密码" name="password">
            </div>
            <button type="submit" class="btn btn-primary block full-width m-b">登录</button>


        </form>
    </div>
</div>

<!-- Mainly scripts -->
<script src="/static/js/jquery-3.1.1.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/validate/jquery.validate.js"></script>
<script src="/static/js/plugins/validate/messages_zh.js"></script>
<script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
<script>
    $(document).ready(function () {
        $("#login_form").validate({
            rules: {
                username: {
                    required: true,
                    minlength: 4
                },
                password: {
                    required: true,
                    minlength: 6
                }
            },
            submitHandler: function () {
                var str = $('#login_form').serialize();
                $.post('{% url 'login' %}', str, function (res) {
                    console.log(res)
                    if ( res.status == 0) {
                         location.href = {% url 'index' %}
                    } else {
                       swal({
                            title: res.msg,
                            type: 'error',
                            confirmButtonText: "知道了"
                        });
                    }
                });
            }
            });
    });


</script>

</body>

</html>

image-20231015115320126

2、Django的用户系统实现登录

以上操作,只是实现了登录的基本校验操作,但是没有用户信息,所有实际是不能够使用。

在Django中,提供了整个一套的登录相关方法,可以直接导入调用即可。

from django.contrib.auth import login, logout, authenticate

authenticate():就是用来验证用户的账号密码,如果验证成功就会返回一个User对象,如果失败就会返回None。

login():用来真正执行登录的函数,这里也会生成session存储进数据库。

logout():用来注销用户的。

实现登录功能

视图

dashboard/views.py

from django.shortcuts import render
from django.views.generic import View, TemplateView
from django.http import JsonResponse
from django.contrib.auth import login, logout, authenticate
class BaseView(View):
	def get(self,request):
		return render(request,'base.html')

class IndexView(TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['name'] = 'DevOps'
        return context

class LoginView(TemplateView):
    template_name = 'login.html'

    def post(self, request):
        data = {}
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)
        if user:
            login(request, user)
            data['status'] = 0
            data['msg'] = "登陆成功"
        else:
            data['status'] = 1
            data['msg'] = "账户或密码错误"
        return JsonResponse(data)

image-20231015115902294

image-20231015115917220

模板

image-20231015120046153

使用manager.py创建用户

注意在创建用户密码的时候,不要太弱,和用户名称邮箱雷同,认为不安全

python manage.py createsuperuser
user       admin
email      admin@qq.com
password   fxx123


(cmdb) PS E:\cmdb> python manage.py createsuperuser
用户名 (leave blank to use '86199'): admin
电子邮件地址: admin@qq.com
Password: 
Password (again): 
密码长度太短。密码必须包含至少 8 个字符。
Bypass password validation and create user anyway? [y/N]: y  是否绕过密码验证并创建用户?
Superuser created successfully.

image-20231015120609057

image-20231015120654772

3、URL拦截器

虽然已经实现了登录系统功能,但是发现即使不通过登录系统,也可以直接通过URL访问管理后台的首页。所以,还需要在首页面上进行登录验证。登录允许访问,没有登录不允许访问。

防止通过URL直接访问 防翻墙

Django中提供了验证方法:

from django.contrib.auth.mixins import LoginRequiredMixin

①添加实现

导入类

dashboard/views.py

注意一定要最先继承LoginRequireMixin类

from django.shortcuts import render
from django.views.generic import View, TemplateView
from django.http import JsonResponse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.mixins import LoginRequiredMixin
class BaseView(View):
	def get(self,request):
		return render(request,'base.html')

class IndexView(LoginRequiredMixin,TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['name'] = 'DevOps'
        return context


class LoginView(TemplateView):
    template_name = 'login.html'

    def post(self, request):
        data = {}
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)
        if user:
            login(request, user)
            data['status'] = 0
            data['msg'] = "登陆成功"
        else:
            data['status'] = 1
            data['msg'] = "账户或密码错误"
        return JsonResponse(data)

image-20231015121015572

配置修改默认登录路径

cmdb/settings.py

"""
Django settings for cmdb project.

Generated by 'django-admin startproject' using Django 4.2.6.

For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-79&mig28&5+94g*9zm4h8ey&@+cd5s7e8#wo&6)#_qcjnrf_h*'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'dashboard.apps.DashboardConfig',
]

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',
]

ROOT_URLCONF = 'cmdb.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
	    ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'cmdb.wsgi.application'


# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'cmdb',
        'USER': 'root',
        'PASSWORD': 'fxx123',
        'HOST': '10.0.0.131',
        'PORT': '3306',
        'OPTIONS': {
            "init_command": "SET sql_mode='STRICT_TRANS_TABLES'"
        }
    }
}


# Password validation
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/4.2/topics/i18n/

LANGUAGE_CODE = 'zh-Hans'

TIME_ZONE = 'Asia/Shanghai'

USE_I18N = True

USE_TZ = False


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/

STATIC_URL = 'static/'
STATICFILES_DIRS = [
    # os.path.join(BASE_DIR, 'static')
    BASE_DIR / 'static'
]

LOGIN_URL = '/login/'

# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

image-20231015121819591

image-20231015122115422

4、注销功能实现

注销退出登录功能,使用Django的logout方法实现即可。

注销后,返回登录页面,需要导入类方法

from django.http import HttpResponseRedirect

from django.urls import reverse

注销后通过HttpResponseRedirect跳转页面。

在跳转页面的同时,需要反向去解析URL别名,需要reverse解析方法。

视图

dashboard/views.py

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.views.generic import View, TemplateView
from django.http import JsonResponse
from django.contrib.auth import login, logout, authenticate
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse
class BaseView(View):
	def get(self,request):
		return render(request,'base.html')

class IndexView(LoginRequiredMixin,TemplateView):
    template_name = 'index.html'

    def get_context_data(self, **kwargs):
        context = super(IndexView, self).get_context_data(**kwargs)
        context['name'] = 'DevOps'
        return context


class LoginView(TemplateView):
    template_name = 'login.html'

    def post(self, request):
        data = {}
        username = request.POST.get('username')
        password = request.POST.get('password')
        user = authenticate(username=username, password=password)
        if user:
            login(request, user)
            data['status'] = 0
            data['msg'] = "登陆成功"
        else:
            data['status'] = 1
            data['msg'] = "账户或密码错误"
        return JsonResponse(data)

class LogoutView(View):

    def get(self,request):
        logout(request)
        return  HttpResponseRedirect(reverse('login'))

image-20231015122701663

image-20231015122725135

路由

cmdb/urls.py

from django.contrib import admin
from django.urls import path,include
from django.views.generic import RedirectView
from dashboard.views import *

urlpatterns = [
	path('admin/', admin.site.urls),
	path('',RedirectView.as_view(url='dashboard/')),
	path('login/',LoginView.as_view(),name='login'),
	path('logout/',LogoutView.as_view(),name='logout'),
	path('dashboard/',include('dashboard.urls'))
]

image-20231015123026555

模板

dashboard/templates/login.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>CMDB管理系统</title>

    <link href="/static/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.css" rel="stylesheet">
    <link href="/static/css/plugins/toastr/toastr.min.css" rel="stylesheet">

    <link href="/static/css/animate.css" rel="stylesheet">
    <link href="/static/css/style.css" rel="stylesheet">
    <link rel="stylesheet" href="/static/css/plugins/sweetalert/sweetalert.css">
    {% block load_css %}
    {% endblock %}

</head>
<body>

<div id="wrapper">

    <nav class="navbar-default navbar-static-side" role="navigation">
        <div class="sidebar-collapse">
            <ul class="nav metismenu" id="side-menu">
                <li class="nav-header">
                    <div class="dropdown profile-element" >
                        <a data-toggle="dropdown" class="dropdown-toggle" href="#">
                            <span class="clear"> <span class="block m-t-xs"> <strong class="font-bold">{{ request.user.username }}</strong>
                             </span> <span class="text-muted text-xs block">{{ request.user.groups.filter.0 }}<b class="caret"></b></span> </span>
                        </a>
                        <ul class="dropdown-menu animated fadeInRight m-t-xs">
                            <li><a href="profile.html">个人信息</a></li>
                        </ul>
                    </div>
                </li>
                <li>
                    <a href="{% url 'index' %}"><i class="fa fa-bar-chart-o"></i> <span class="nav-label">首页</span></a>
                </li>
                <li>
                    <a href="../dashboard/templates/index.html"><i class="fa fa-th-large"></i> <span class="nav-label">系统管理</span> <span
                            class="fa arrow"></span></a>
                </li>
                <li>
                    <a href="#"><i class="fa fa-bar-chart-o"></i> <span class="nav-label">资产管理</span><span
                            class="fa arrow"></span></a>
                </li>
            </ul>

        </div>
    </nav>

    <div id="page-wrapper" class="gray-bg">
        <div class="row border-bottom">
            <nav class="navbar navbar-static-top  " role="navigation" style="margin-bottom: 0">
                <div class="navbar-header">
                    <a class="navbar-minimalize minimalize-styl-2 btn btn-primary " href="#"><i class="fa fa-bars"></i>
                    </a>
                </div>
                <ul class="nav navbar-top-links navbar-right">
                    <li>
                        <span class="m-r-sm text-muted welcome-message">欢迎来到配置数据库管理系统 </span>                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </欢迎来到SYSCMDB自动化管理系统></span>
                    </li>
                        <a href="{% url 'logout' %}">
                            <i class="fa fa-sign-out"></i> 登出
                        </a>
                </ul>

            </nav>
        </div>

        {% block mbx %}
            <div class="row wrapper border-bottom white-bg page-heading">
                <div class="col-sm-4">
                    <h2>仪表盘</h2>
                    <ol class="breadcrumb">
                        <li>
                            <a href="../dashboard/templates/index.html">首页</a>
                        </li>
                    </ol>
                </div>
            </div>
        {% endblock %}

        {% block body %}
            <h1>这是BASE页面</h1>
        {% endblock %}

    </div>

</div>


<!-- Mainly scripts -->
<script src="/static/js/jquery-3.1.1.min.js"></script>
<script src="/static/js/bootstrap.min.js"></script>
<script src="/static/js/plugins/metisMenu/jquery.metisMenu.js"></script>
<script src="/static/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>

<!-- Custom and plugin javascript -->
<script src="/static/js/inspinia.js"></script>
<script src="/static/js/plugins/pace/pace.min.js"></script>
<script src="/static/js/plugins/validate/jquery.validate.js"></script>
<script src="/static/js/plugins/validate/messages_zh.js"></script>
<script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
<script>
    function aaa(i){
        console.log(i)
    }

    </script>
{% block load_js %}

{% endblock %}

</body>

</html>

image-20231015123418264

image-20231015123701550

5、登录原理解析(扩展)

在这里插入图片描述

会话机制,http每次连接默认没有上下联系状态。

cookie 存储在浏览器中的一些信息,具有风险,容易被篡改

image-20231015124042831

session 存储到服务器的一些信息

image-20231015124152343

通过查看相关信息,确认流程

退出登录的方式:

1、清空cookie
如果在浏览器清除了cookie信息,就会退出登录
cookie里记录了session_id,没有session_id就不能够找到session,所以就被判断为未登录

2、清空session
直接删除session信息,虽然cookie在,session没有了,也会判定为未登录

五、用户管理模块

1、展示用户列表

用户登录之后,继续实现用户管理模块。

首先展示用户列表信息,为了方便管理项目应用,创建新应用users,负责用户管理模块,用户组管理模块和权限管理模块的开发和管理。

创建新应用

python manage.py startapp users

image-20231015130624615

配置允许应用

cmdb/settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'dashboard.apps.DashboardConfig',
    'users',
]

image-20231015130743112

路由

cmdb/urls.py

from django.contrib import admin
from django.urls import path,include
from django.views.generic import RedirectView
from dashboard.views import *

urlpatterns = [
	path('admin/', admin.site.urls),
	path('',RedirectView.as_view(url='dashboard/')),
	path('login/',LoginView.as_view(),name='login'),
	path('logout/',LogoutView.as_view(),name='logout'),
	path('dashboard/',include('dashboard.urls')),
	path('users/',include('users.urls')),
]

image-20231015130942663

users/urls.py

from django.urls import path
from users.views import *

urlpatterns = [
    path('list/', UserListView.as_view(), name='user_list'),
]

image-20231015132455642

视图

users/views.py

from django.shortcuts import render
from django.views.generic import TemplateView
class UserListView(TemplateView):
    template_name = 'user_list.html'

image-20231015131658172

模板

users/templates/user_list.html

{% extends 'base.html' %}
 
{% block mbx %}
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>用户展示</h2>
            <ol class="breadcrumb">
                <li>
                    <a hreaf="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="">用户管理</a>
                </li>
                <li>
                    <a href="">用户展示</a>
                </li>
            </ol>
        </div>
    </div>
{% endblock %}
 
{% block body %}
    <div class="col-lg-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>用户展示 </h5>
            </div>
            <div class="ibox-content">
 
                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">用户名</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">微信</th>
                        <th class="text-center">中文名</th>
                        <th class="text-center">电话</th>
                        <th class="text-center">激活状态</th>
                        <th class="text-center">操作</th>
                    </tr>
                    </thead>
                    <tbody>
{#                    {% for one in data %}#}
{#                    <tr>#}
{#                        <td class="text-center">{{ one.username }}</td>#}
{#                        <td class="text-center">{{ one.email }}</td>#}
{#                        <td class="text-center"></td>#}
{#                        <td class="text-center"></td>#}
{#                        <td class="text-center"></td>#}
{#                        {% if one.is_active == 1 %}#}
{#                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>#}
{#                        {% else %}#}
{#                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>#}
{#                        {% endif %}#}
{#                        <td class="text-center">#}
{#                            <button type="button" class="btn btn-primary btn-sm">更新</button>#}
{#                            <button type="button" class="btn btn-danger btn-sm">删除</button>#}
{#                        </td>#}
{#                    </tr>#}
{#                    {% endfor %}#}
                      <tr>
                        <td class="text-center">admin</td>
                        <td class="text-center">admin@qq.com</td>
                        <td class="text-center">admin123</td>
                        <td class="text-center">超级管理员</td>
                        <td class="text-center">13999999999</td>
                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
                        <td class="text-center">
                            <button type="button" class="btn btn-primary btn-sm">更新</button>
                            <button type="button" class="btn btn-danger btn-sm">删除</button>
                        </td>
                    </tr>
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}

image-20231015132201376

image-20231015132417739

上面实现了页面加载,获取数据库用户信息,显示到模板页面

视图

users/views.py

from django.shortcuts import render
from django.views.generic import View
from django.contrib.auth.models import User
# Create your views here.
class UserListView(View):
    def get(self, request):
        data = User.objects.all()
        return render(request, 'user_list.html', {'data': data})

image-20231015143254019

模板

users/templates/user_list.html

{% extends 'base.html' %}
 
{% block mbx %}
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>用户展示</h2>
            <ol class="breadcrumb">
                <li>
                    <a hreaf="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="">用户管理</a>
                </li>
                <li>
                    <a href="">用户展示</a>
                </li>
            </ol>
        </div>
    </div>
{% endblock %}
 
{% block body %}
    <div class="col-lg-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>用户展示 </h5>
            </div>
            <div class="ibox-content">
 
                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">用户名</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">微信</th>
                        <th class="text-center">中文名</th>
                        <th class="text-center">电话</th>
                        <th class="text-center">激活状态</th>
                        <th class="text-center">操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for one in data %}
                    <tr>
                        <td class="text-center">{{ one.username }}</td>
                        <td class="text-center">{{ one.email }}</td>
                        <td class="text-center"></td>
                        <td class="text-center"></td>
                        <td class="text-center"></td>
                        {% if one.is_active == 1 %}
                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                        {% else %}
                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
                        {% endif %}
                        <td class="text-center">
                            <button type="button" class="btn btn-primary btn-sm">更新</button>
                            <button type="button" class="btn btn-danger btn-sm">删除</button>
                        </td>
                    </tr>
                    {% endfor %}
{#                      <tr>#}
{#                        <td class="text-center">admin</td>#}
{#                        <td class="text-center">admin@qq.com</td>#}
{#                        <td class="text-center">admin123</td>#}
{#                        <td class="text-center">超级管理员</td>#}
{#                        <td class="text-center">13999999999</td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>#}
{#                        <td class="text-center">#}
{#                            <button type="button" class="btn btn-primary btn-sm">更新</button>#}
{#                            <button type="button" class="btn btn-danger btn-sm">删除</button>#}
{#                        </td>#}
{#                    </tr>#}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
{% endblock %}

image-20231015143334952

为了看到数据动态的效果,可以再通过 django添加用户测试

python manage.py createsuperuser
username:             root
Password:             123.com
Password (again):     123.com
密码长度太短。密码必须包含至少 8 个字符。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

image-20231015143353959

以下代码通过判断用户状态在页面显示用户是否处于激活状态,激活状态字段值为1 修改成其他值则会在页面显示红色

users/templates/user_list.html

{% if one.is_active == 1 %}
                      <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                          {% else %}
                     <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
{% endif %}

image-20231015143842639

mysql> update auth_user set is_active=0 where id=2;

image-20231015143914405

2、扩展基础用户表

Django的用户表中,提供了基本必须字段:用户名称、邮箱、密码、角色(超级管理员、普通用户)

需要添加更多的用户信息,需要使用OneToOneField字段对用户表进行拓展。

OneToOneField就是一对一,跟多对一的使用类似,也有正向反向查询

扩展模型

加入中文名、微信、电话 备注等

导入基础用户模型

users/models.py

from django.db import models
from django.contrib.auth.models import User,Group
# Create your models here.

class Profile(models.Model): # 个人信息
    user = models.OneToOneField(User,on_delete=models.CASCADE)
    name_cn = models.CharField(max_length=32,verbose_name="中文名")
    wechat = models.CharField(max_length=32,verbose_name="微信")
    phone = models.CharField(max_length=11,verbose_name="电话")
    info = models.TextField(verbose_name="备注")

image-20231015144240668

迁移数据表

python manage.py makemigrations   # 生成迁移表
python manage.py migrate           # 进行数据迁移

image-20231015144450847

image-20231015144603953

插入数据

insert into users_profile values(null,'运维开发','fxx','18866568972','运维部',1);

修改模板

users/templates/user_list.html

{% extends 'base.html' %}
{% if one.is_active == 1 %}
                      <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                          {% else %}
                     <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
{% endif %}

{% block mbx %}
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>用户展示</h2>
            <ol class="breadcrumb">
                <li>
                    <a hreaf="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="">用户管理</a>
                </li>
                <li>
                    <a href="">用户展示</a>
                </li>
            </ol>
        </div>
    </div>
{% endblock %}

{% block body %}
    <div class="col-lg-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>用户展示 </h5>
            </div>
            <div class="ibox-content">

                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">用户名</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">微信</th>
                        <th class="text-center">中文名</th>
                        <th class="text-center">电话</th>
                        <th class="text-center">激活状态</th>
                        <th class="text-center">操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for one in data %}
                    <tr>
                        <td class="text-center">{{ one.username }}</td>
                        <td class="text-center">{{ one.email }}</td>
                        <td class="text-center">{{ one.profile.wechat }}</td>
                        <td class="text-center">{{ one.profile.name_cn }}</td>
                        <td class="text-center">{{ one.profile.phone }}</td>
                        {% if one.is_active == 1 %}
                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                        {% else %}
                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
                        {% endif %}
                        <td class="text-center">
                            <button type="button" class="btn btn-primary btn-sm">更新</button>
                            <button type="button" class="btn btn-danger btn-sm">删除</button>
                        </td>
                    </tr>
                    {% endfor %}
{#                      <tr>#}
{#                        <td class="text-center">admin</td>#}
{#                        <td class="text-center">admin@qq.com</td>#}
{#                        <td class="text-center">admin123</td>#}
{#                        <td class="text-center">超级管理员</td>#}
{#                        <td class="text-center">13999999999</td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>#}
{#                        <td class="text-center">#}
{#                            <button type="button" class="btn btn-primary btn-sm">更新</button>#}
{#                            <button type="button" class="btn btn-danger btn-sm">删除</button>#}
{#                        </td>#}
{#                    </tr>#}
                    </tbody>
                </table>
            </div>
        </div>
    </div>

{% endblock %}

image-20231015145054778

页面展示效果

image-20231015145259766

3、高级视图类之ListView

上面的案例中使用高级视图类TemplateView,这里再使用另外一个高级视图类ListView

使用ListView 定义模型名称 数据会自动查询 并且组合

视图

users/views.py

from django.shortcuts import render
from django.views.generic import View,ListView
from django.contrib.auth.models import User

# class UserListView(View):
#     def get(self, request):
#         data = User.objects.all()
#         return render(request, 'user_list.html', {'data': data})
    
class UserListView(ListView):
    template_name = 'user_list.html'
    model = User

    def get_context_data(self, **kwargs):
        content = super(UserListView, self).get_context_data(**kwargs)
        print(content)
        return content

image-20231015151612624

模板

路由保持不变 修改模板遍历object_list

image-20231015151153863

页面展示效果不变

4、批量创建用户

路由

users/urls.py

from django.urls import path
from users.views import *

urlpatterns = [
    path('list/', UserListView.as_view(), name='user_list'),
    path('testdata',TestDataView.as_view()),
]

image-20231015152110696

视图

users/views.py

from django.shortcuts import render
from django.views.generic import View
from django.contrib.auth.models import User
# Create your views here.
class UserListView(View):
    def get(self, request):
        data = User.objects.all()
        return render(request, 'user_list.html', {'data': data})
class TestDataView(View):
    def get(self, request):
        for i in range(1, 100):
            user = User()
            profile = Profile()
            user.username = 'user{}'.format(i)
            user.password = make_password('123456')
            user.email = '{}.qq@com'.format(i)
            user.save()
            profile.user_id = user.id
            profile.name_cn = '用户{}'.format(i)
            profile.wechat = 'wechat_user{}'.format(i)
            profile.phone = '133333333{}'.format(i)
            profile.info = '测试用户{}'.format(i)
            profile.save()

image-20231015161802422

访问web页面创建用户

http://127.0.0.1:8000/users/testdata

image-20231015161732967

image-20231015161833176

5、分页实现

一次性展示数据太多了,需要进行分页显示处理。

分页原理

视图

通过高级视图ListView实现

users/views.py

class UserListView(ListView):
    template_name = 'user_list.html'
    model = User
    paginate_by = 10   # 每页显示10条

    def get_context_data(self, **kwargs):
        content = super(UserListView, self).get_context_data(**kwargs)
        print(content)
        return content

image-20231015162251924

显示页面按钮

page_obj.has_previous 判断是否有上一页
page_obj.previous_page_number 上一页的页数对象
page_obj.number 当前页数
page_obj.has_next 判断是否有下一页
page_obj.next_page_number 下一页的页面对象
paginator.num_pages 最大页数
paginator. page_range 可迭代的总页数

模板

users/templates/user_list.html

{% extends 'base.html' %}
{% if one.is_active == 1 %}
                      <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                          {% else %}
                     <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
{% endif %}

{% block mbx %}
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>用户展示</h2>
            <ol class="breadcrumb">
                <li>
                    <a hreaf="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="">用户管理</a>
                </li>
                <li>
                    <a href="">用户展示</a>
                </li>
            </ol>
        </div>
    </div>
{% endblock %}

{% block body %}
    <div class="col-lg-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>用户展示 </h5>
            </div>
            <div class="ibox-content">

                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">用户名</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">微信</th>
                        <th class="text-center">中文名</th>
                        <th class="text-center">电话</th>
                        <th class="text-center">激活状态</th>
                        <th class="text-center">操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for one in object_list %}
                    <tr>
                        <td class="text-center">{{ one.username }}</td>
                        <td class="text-center">{{ one.email }}</td>
                        <td class="text-center">{{ one.profile.wechat }}</td>
                        <td class="text-center">{{ one.profile.name_cn }}</td>
                        <td class="text-center">{{ one.profile.phone }}</td>
                        {% if one.is_active == 1 %}
                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                        {% else %}
                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
                        {% endif %}
                        <td class="text-center">
                            <button type="button" class="btn btn-primary btn-sm">更新</button>
                            <button type="button" class="btn btn-danger btn-sm">删除</button>
                        </td>
                    </tr>
                    {% endfor %}
{#                      <tr>#}
{#                        <td class="text-center">admin</td>#}
{#                        <td class="text-center">admin@qq.com</td>#}
{#                        <td class="text-center">admin123</td>#}
{#                        <td class="text-center">超级管理员</td>#}
{#                        <td class="text-center">13999999999</td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>#}
{#                        <td class="text-center">#}
{#                            <button type="button" class="btn btn-primary btn-sm">更新</button>#}
{#                            <button type="button" class="btn btn-danger btn-sm">删除</button>#}
{#                        </td>#}
{#                    </tr>#}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
<center>
                    <div class="btn-group">
                        {% if page_obj.has_previous %}
                            <a type="button" class="btn btn-white"
                               href="{% url 'user_list' %}?page={{ page_obj.previous_page_number }}"><i
                                    class="fa fa-chevron-left"></i></a>
                        {% endif %}
                        {% for i in  paginator.page_range %}
                            {% if page_obj.number == i %}
                                <a class="btn btn-white active" href="{% url 'user_list' %}?page={{ i }}">{{ i }}</a>
                            {% else %}
                                <a class="btn btn-white" href="{% url 'user_list' %}?page={{ i }}">{{ i }}</a>
                            {% endif %}
                        {% endfor %}
                        {% if page_obj.has_next %}
                            <a type="button" class="btn btn-white"
                               href="{% url 'user_list' %}?page={{ page_obj.next_page_number }}"><i
                                    class="fa fa-chevron-right"></i> </a>
                        {% endif %}
                    </div>
                </center>
            </div>
        </div>
    </div>
    <script>
    </script>
{% endblock %}

限制输出的页面按钮数量

视图

users/views.py

from django.shortcuts import render
from django.views.generic import View,ListView
from django.contrib.auth.models import User
from users.models import *
from django.contrib.auth.hashers import make_password,check_password
# Create your views here.
# class UserListView(View):
#     def get(self, request):
#         data = User.objects.all()
#         return render(request, 'user_list.html', {'data': data})

class UserListView(ListView):
    template_name = 'user_list.html'
    model = User
    paginate_by = 10   # 每页显示10条

    def get_context_data(self, **kwargs):
        content = super(UserListView, self).get_context_data(**kwargs)
        print(content)
        return content

    def page_range(self, page_obj, paginator):
        current_index = page_obj.number
        start = current_index - 2
        end = current_index + 3
        if start <= 1:
            start = 1
        if end >= paginator.num_pages:
            end = paginator.num_pages + 1
        current_pages_num = end - start
        if (end == paginator.num_pages + 1):
            start = start - (5 - current_pages_num)
        else:
            if current_pages_num < 5:
                end = end + (5 - current_pages_num)
        return range(start, end)
class TestDataView(View):
    def get(self, request):
        for i in range(1, 100):
            user = User()
            profile = Profile()
            user.username = 'user{}'.format(i)
            user.password = make_password('123456')
            user.email = '{}.qq@com'.format(i)
            user.save()
            profile.user_id = user.id
            profile.name_cn = '用户{}'.format(i)
            profile.wechat = 'wechat_user{}'.format(i)
            profile.phone = '133333333{}'.format(i)
            profile.info = '测试用户{}'.format(i)
            profile.save()

image-20231015165652597

image-20231015170325221

6、添加用户

用户列表展示出来。之前创建用户是在命令行创建,实际业务中,需要在页面中添加用户。

点击添加按钮,通过表单结合ajax提交到后端,实现添加用户功能。

Tip:继承页面css和js处理

路由

users/urls.py

from django.urls import path
from users.views import *

urlpatterns = [
    path('list/', UserListView.as_view(), name='user_list'),
    path('add/', UserAddView.as_view(), name='user_add'),
]

image-20231015171644066

视图

users/views.py

class UserAddView(TemplateView):
    template_name = 'user_add.html'

    def post(self, request):
        data = request.POST
        res = {'status': 0, 'msg': '添加成功'}
        try:
            user = User()
            user.username = data.get('username')
            user.password = make_password(data.get('password'))
            user.mail = data.get('email')
            user.save()

            profile = Profile()
            profile.user_id = user.id  # 这里给 user_id 字段赋值
            profile.name_cn = data.get('name_cn')
            profile.wechat = data.get('wechat')
            profile.phone = data.get('phone')
            info = data.get('info')
            if info is None or info == '':  # 检查 'info' 字段是否为空
                info = "默认值"  # 给 'info' 字段赋值一个默认值
            profile.info = info  # 这里给 info 字段赋值
            profile.save()

        except Exception as e:
            print(e)
            res = {'status': 1, 'msg': '添加失败'}

        return JsonResponse(res)

image-20231015170908644

前端模板

users/templates/user_add.html

{% extends 'base.html' %}

{% block mbx %}
     <div class="col-lg-12">
        <div class="ibox float-e-margins">
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>创建用户</h2>
            <ol class="breadcrumb">
                <li>
                    <a href="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="{% url 'user_list' %}">用户管理</a>
                </li>
                <li>
                    <a href="">创建用户</a>
                </li>
            </ol>
        </div>
     </div>
         </div>
    </div>
{% endblock %}

{% block body %}
    <div class="ibox-content">
        <form id="submit_form" class="form-horizontal">
            {% csrf_token %}
            <div class="form-group"><label class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="username"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">中文名</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="name_cn"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">密码</label>
                <div class="col-sm-6"><input type="password" class="form-control" name="password"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-6"><input type="email" class="form-control" name="email"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">微信</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="wechat"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">电话</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="phone"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group">
                <div class="col-sm-4 col-sm-offset-2">
                    <a class="btn btn-white" type="submit" href="javascript:history.back(-1)">取消</a>
                    <button class="btn btn-primary" type="submit">保存更改</button>
                </div>
            </div>
        </form>
    </div>
{% endblock %}

{% block load_js %}
    <script>
        $(document).ready(function () {
            $("#submit_form").validate({
                rules: {
                    name_cn: {
                        required: true
                    },
                    username: {
                        required: true
                    },
                    email: {
                        required: true
                    },
                    password: {
                        required: true
                    },
                    phone: {
                        required: true,
                        minlength:11
                    },
                    wechat: {
                        required: true
                    }
                }, submitHandler: function () {
                    var str = $('#submit_form').serialize();
                    $.post('{% url 'user_add' %}', str, function (res) {
                        if (res.status == 0) {
                            swal({
                                title: res.msg,
                                type: 'success',
                                confirmButtonText: "确定"
                            }, function () {
                                window.location.href = '{% url 'user_list' %}';
                            });
                        } else {
                            swal({
                                title: res.msg,
                                type: 'error',
                                confirmButtonText: "确定"
                            });
                        }
                    });
                }
            });
        });
    </script>
{% endblock %}

image-20231015171026716

user_list增加一个添加用户的跳转按钮

users/templates/user_list.html

{% extends 'base.html' %}
{% if one.is_active == 1 %}
                      <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                          {% else %}
                     <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
{% endif %}

{% block mbx %}
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>用户展示</h2>
            <ol class="breadcrumb">
                <li>
                    <a hreaf="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="">用户管理</a>
                </li>
                <li>
                    <a href="">用户展示</a>
                </li>
            </ol>
        </div>
    </div>
{% endblock %}

{% block body %}
    <a type="butten" class="btn btn-info" href="{% url 'user_add' %}">添加用户</a>
    <div class="col-lg-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>用户展示 </h5>
            </div>
            <div class="ibox-content">

                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">用户名</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">微信</th>
                        <th class="text-center">中文名</th>
                        <th class="text-center">电话</th>
                        <th class="text-center">激活状态</th>
                        <th class="text-center">操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for one in object_list %}
                    <tr>
                        <td class="text-center">{{ one.username }}</td>
                        <td class="text-center">{{ one.email }}</td>
                        <td class="text-center">{{ one.profile.wechat }}</td>
                        <td class="text-center">{{ one.profile.name_cn }}</td>
                        <td class="text-center">{{ one.profile.phone }}</td>
                        {% if one.is_active == 1 %}
                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                        {% else %}
                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
                        {% endif %}
                        <td class="text-center">
                            <button type="button" class="btn btn-primary btn-sm">更新</button>
                            <button type="button" class="btn btn-danger btn-sm">删除</button>
                        </td>
                    </tr>
                    {% endfor %}
{#                      <tr>#}
{#                        <td class="text-center">admin</td>#}
{#                        <td class="text-center">admin@qq.com</td>#}
{#                        <td class="text-center">admin123</td>#}
{#                        <td class="text-center">超级管理员</td>#}
{#                        <td class="text-center">13999999999</td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>#}
{#                        <td class="text-center">#}
{#                            <button type="button" class="btn btn-primary btn-sm">更新</button>#}
{#                            <button type="button" class="btn btn-danger btn-sm">删除</button>#}
{#                        </td>#}
{#                    </tr>#}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
<center>
                    <div class="btn-group">
                        {% if page_obj.has_previous %}
                            <a type="button" class="btn btn-white"
                               href="{% url 'user_list' %}?page={{ page_obj.previous_page_number }}"><i
                                    class="fa fa-chevron-left"></i></a>
                        {% endif %}
                        {% for i in  paginator.page_range %}
                            {% if page_obj.number == i %}
                                <a class="btn btn-white active" href="{% url 'user_list' %}?page={{ i }}">{{ i }}</a>
                            {% else %}
                                <a class="btn btn-white" href="{% url 'user_list' %}?page={{ i }}">{{ i }}</a>
                            {% endif %}
                        {% endfor %}
                        {% if page_obj.has_next %}
                            <a type="button" class="btn btn-white"
                               href="{% url 'user_list' %}?page={{ page_obj.next_page_number }}"><i
                                    class="fa fa-chevron-right"></i> </a>
                        {% endif %}
                    </div>
                </center>
            </div>
        </div>
    </div>
    <script>
    </script>
{% endblock %}

image-20231015171826956

image-20231015171859232

image-20231015172013697

7、更新用户

路由

users/urls.py

from django.urls import path
from users.views import *

urlpatterns = [
    path('list/', UserListView.as_view(), name='user_list'),
    path('add/', UserAddView.as_view(), name='user_add'),
    path('update/', UserUpdateView.as_view(), name='user_update'),
]

image-20231015172334682

视图

users/views.py

class UserUpdateView(View):
    def get(self, request):
        return render(request, 'user_update.html', {'user_obj': User.objects.get(id=request.GET.get('id'))})

    def post(self, request):
        data = request.POST
        res = {'status': 0, 'msg': '修改成功'}
        try:
            user = User.objects.get(id=data.get('uid'))
            profile = Profile.objects.get(user_id=data.get('uid'))
            user.username = data.get('username')
            user.password = make_password(data.get('password'))
            user.mail = data.get('email')
            user.save()
            profile.profile_id = user.id
            profile.name_cn = data.get('name_cn')
            profile.wechat = data.get('wechat')
            profile.phone = data.get('phone')
            info = data.get('info')
            if info is None:
                # 将info设为NULL或者设置一个默认值
                info = ''
            profile.info = info
            profile.save()
        except Exception as e:
            print(e)
            res = {'status': 1, 'msg': '修改失败'}

        return JsonResponse(res)

前端模板

user_update.html模板

{% extends 'base.html' %}
 
{% block load_css %}
    <link href="/static/css/plugins/sweetalert/sweetalert.css" rel="stylesheet">
{% endblock %}
 
{% block body %}
    <h1>更新用户:{{ user_obj.username }}</h1>
    <div class="ibox-content">
        <form id="submit_form" class="form-horizontal">
            {% csrf_token %}
            <div class="form-group"><label class="col-sm-2 control-label">用户名</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="username" value="{{ user_obj.username }}"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">中文名</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="name_cn" value="{{ user_obj.profile.name_cn }}"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">密码</label>
                <div class="col-sm-6"><input type="password" class="form-control" name="password"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">邮箱</label>
                <div class="col-sm-6"><input type="email" class="form-control" name="email" value="{{ user_obj.email }}"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">微信</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="wechat" value="{{ user_obj.profile.wechat }}"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">电话</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="phone" value="{{ user_obj.profile.phone }}"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group"><label class="col-sm-2 control-label">简介</label>
                <div class="col-sm-6"><input type="text" class="form-control" name="info" value="{{ user_obj.profile.info }}"></div>
            </div>
            <div class="hr-line-dashed"></div>
            <div class="form-group">
                <div class="col-sm-4 col-sm-offset-2">
                    <input type="hidden" value="{{ user_obj.id }}" name="uid">
                    <a class="btn btn-white" type="submit" href="javascript:history.back(-1)">取消</a>
                    <button class="btn btn-primary" type="submit">保存更改</button>
                </div>
            </div>
        </form>
    </div>
{% endblock %}
 
{% block load_js %}
    <script src="/static/js/plugins/validate/jquery.validate.js"></script>
    <script src="/static/js/plugins/validate/messages_zh.js"></script>
    <script src="/static/js/plugins/sweetalert/sweetalert.min.js"></script>
    <script>
        $(document).ready(function () {
            $("#submit_form").validate({
                rules: {
                    name_cn: {
                        required: true
                    },
                    username: {
                        required: true
                    },
                    email: {
                        required: true
                    },
                    password: {
                        required: true
                    },
                    phone: {
                        required: true
                    },
                    wechat: {
                        required: true
                    }
                }, submitHandler: function () {
                    var str = $('#submit_form').serialize();
                    $.post('{% url 'user_update' %}', str, function (res) {
                        if (res.status == 0) {
                            swal({
                                title: res.msg,
                                type: 'success',
                                confirmButtonText: "确定"
                            }, function () {
                                window.location.href = '{% url 'user_list' %}';
                            });
                        } else {
                            swal({
                                title: res.msg,
                                type: 'error',
                                confirmButtonText: "确定"
                            });
                        }
                    });
                }
            });
        });
    </script>
{% endblock %}

image-20231015172706731

user_list模板修改跳转链接

<a type="button" class="btn btn-primary btn-sm" href="{% url 'user_update' %}?id={{ one.id }}">更新</a>

image-20231015173505142

image-20231015173520945

8、删除用户

路由

users/urls.py

from django.urls import path
from users.views import *

urlpatterns = [
    path('list/', UserListView.as_view(), name='user_list'),
    path('add/', UserAddView.as_view(), name='user_add'),
    path('update/', UserUpdateView.as_view(), name='user_update'),
    path('delete/', UserDeleteView.as_view(), name='user_delete'),
]

视图

users/views.py

class UserDeleteView(View):
    def get(self, request):
        uid = request.GET.get('uid')
        res = {'status': 0, 'msg': "更新成功"}
        try:
            User.objects.get(id=uid).delete()
            print(User.DoesNotExist)
        except User.DoesNotExist:
            res = {'status': 1, 'msg': '用户不存在,删除失败'}
        except Exception:
            res = {'status': 1, 'msg': '未知错误'}
        return JsonResponse(res)

模板

<a type="button" class="btn btn-danger btn-sm" onclick="user_delete({{ one.id }})">删除</a>

image-20231015180046228

删除函数

users/templates/user_list.html

{% extends 'base.html' %}
{% if one.is_active == 1 %}
                      <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                          {% else %}
                     <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
{% endif %}

{% block mbx %}
    <div class="row wrapper border-bottom white-bg page-heading">
        <div class="col-sm-4">
            <h2>用户展示</h2>
            <ol class="breadcrumb">
                <li>
                    <a hreaf="{% url 'index' %}">首页</a>
                </li>
                <li>
                    <a href="">用户管理</a>
                </li>
                <li>
                    <a href="">用户展示</a>
                </li>
            </ol>
        </div>
    </div>
{% endblock %}

{% block body %}
    <a type="butten" class="btn btn-info" href="{% url 'user_add' %}">添加用户</a>
    <div class="col-lg-12">
        <div class="ibox float-e-margins">
            <div class="ibox-title">
                <h5>用户展示 </h5>
            </div>
            <div class="ibox-content">

                <table class="table table-striped">
                    <thead>
                    <tr>
                        <th class="text-center">用户名</th>
                        <th class="text-center">邮箱</th>
                        <th class="text-center">微信</th>
                        <th class="text-center">中文名</th>
                        <th class="text-center">电话</th>
                        <th class="text-center">激活状态</th>
                        <th class="text-center">操作</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for one in object_list %}
                    <tr>
                        <td class="text-center">{{ one.username }}</td>
                        <td class="text-center">{{ one.email }}</td>
                        <td class="text-center">{{ one.profile.wechat }}</td>
                        <td class="text-center">{{ one.profile.name_cn }}</td>
                        <td class="text-center">{{ one.profile.phone }}</td>
                        {% if one.is_active == 1 %}
                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>
                        {% else %}
                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>
                        {% endif %}
                        <td class="text-center">
                            <a type="button" class="btn btn-primary btn-sm" href="{% url 'user_update' %}?id={{ one.id }}">更新</a>
                            <a type="button" class="btn btn-danger btn-sm" onclick="user_delete({{ one.id }})">删除</a>
                        </td>
                    </tr>
                    {% endfor %}
{#                      <tr>#}
{#                        <td class="text-center">admin</td>#}
{#                        <td class="text-center">admin@qq.com</td>#}
{#                        <td class="text-center">admin123</td>#}
{#                        <td class="text-center">超级管理员</td>#}
{#                        <td class="text-center">13999999999</td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-navy"></i></td>#}
{#                        <td class="text-center"><i class="fa fa-circle text-danger"></i></td>#}
{#                        <td class="text-center">#}
{#                            <button type="button" class="btn btn-primary btn-sm">更新</button>#}
{#                            <button type="button" class="btn btn-danger btn-sm">删除</button>#}
{#                        </td>#}
{#                    </tr>#}
                    </tbody>
                </table>
            </div>
        </div>
    </div>
<center>
                    <div class="btn-group">
                        {% if page_obj.has_previous %}
                            <a type="button" class="btn btn-white"
                               href="{% url 'user_list' %}?page={{ page_obj.previous_page_number }}"><i
                                    class="fa fa-chevron-left"></i></a>
                        {% endif %}
                        {% for i in  paginator.page_range %}
                            {% if page_obj.number == i %}
                                <a class="btn btn-white active" href="{% url 'user_list' %}?page={{ i }}">{{ i }}</a>
                            {% else %}
                                <a class="btn btn-white" href="{% url 'user_list' %}?page={{ i }}">{{ i }}</a>
                            {% endif %}
                        {% endfor %}
                        {% if page_obj.has_next %}
                            <a type="button" class="btn btn-white"
                               href="{% url 'user_list' %}?page={{ page_obj.next_page_number }}"><i
                                    class="fa fa-chevron-right"></i> </a>
                        {% endif %}
                    </div>
                </center>
    <script>
        function user_delete(id) {
            if (confirm('确认删除吗?')) {
            {#alert(id)#}
                $.get("{% url 'user_delete' %}?id=" + id,function (data) {
                if(data.status == 0) {
                    swal({
                        title: data.msg,
                        icon: "success",
                        confirmButtonText: '确定',
                    }, function () {
                        window.location.reload()
                    });
                    } else {
                    swal("删除失败", {
                        icon: "error",
                    });
                }
            });
            }
        }
    </script>
{% endblock %}

9、禁用和启用用户

路由

urlpatterns = [
    path('list/', UserListView.as_view(), name='user_list'),
    path('add/', UserAddView.as_view(), name='user_add'),
    path('update/', UserUpdateView.as_view(), name='user_update'),
    path('delete/', UserDeleteView.as_view(), name='user_delete'),
    path('status/',UserStatusView.as_view(),name='user_status'),
]

视图

class UserStatusView(View):
    def get(self, request):
        data = request.GET
        # 判断当前用户是禁用还是启用
        # 用户是禁用则启用 用户是启用则禁用
        res = {'status': 0, 'msg': '用户状态更新成功'}
        # 查询用户当前状态
        user = User.objects.get(id=data.get('id'))
        status = user.is_active
        # 确定用户跟新的新状态
        if status == 0:
            newstatus = 1
        else:
            newstatus = 0
        try:
            user = User.objects.get(id=data.get('id'))
            user.is_active = newstatus
            user.save()
        except Exception as e:
            print(e)
            res = {'status': 1, 'msg': '用户状态更新失败'}
        return JsonResponse(res)

模板

增加两个按钮,查询状态如果用户是启用状态则显示禁用按钮,如果用户是禁用状态则显示启用按钮


function user_status(id) {
         $.get("{% url 'user_status' %}?id=" + id,function (data) {
             if(data.status == 0) {
                 swal({
                     title: data.msg,
                     icon: "success",
                     confirmButtonText: '确定',
                 }, function () {
                     window.location.reload()
                 });
                 } else {
                   swal({
                         title: data.msg,
                         icon: "error",
                         confirmButtonText: '确定',
                     },function () {
                       });
                     }
                 });
         }

image-20231016094426651

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python Django 是一个流行的 Web 框架,可以用于快速开发高质量的 Web 应用程序。在 Django 中,一个应用程序可以由多个模块组成,并且可以轻松地与其他应用程序集成。在这里,我将为您提供一些建议和指导,以帮助您开始使用 Django 构建学生管理系统。 1. 安装 Django: 首先,你需要安装 Django。你可以通过 pip 命令安装 Django,例如:`pip install django` 2. 创建一个 Django 项目: 接下来,你需要创建一个 Django 项目。你可以运行以下命令来创建一个名为 myproject 的新项目:`django-admin startproject myproject` 3. 创建一个 Django 应用程序: 接下来,你需要创建一个名为 students 的新应用程序。你可以运行以下命令:`python manage.py startapp students` 4. 配置数据库: Django 默认使用 SQLite 数据库。如果你想使用其他数据库(如 MySQL 或 PostgreSQL),你需要修改 myproject/settings.py 文件中的 DATABASES 设置。 5. 创建模型: 在 Django 中,模型是与数据库表对应的 Python 类。你需要在 students/models.py 文件中创建一个名为 Student 的模型,包括学生的姓名、年龄和成绩。 6. 进行数据库迁移: 在创建模型后,你需要运行以下命令来将模型同步到数据库中:`python manage.py makemigrations students`,然后运行 `python manage.py migrate` 命令进行数据库迁移。 7. 创建视图: 视图是 Django 应用程序中处理请求和生成响应的代码。你需要在 students/views.py 文件中创建一个名为 student_list 的视图,用于显示所有学生的列表。 8. 创建 URL: URL 是 Django 应用程序中的网址,它将请求路由到正确的视图。你需要在 students/urls.py 文件中创建一个 URL 模式,将 student_list 视图与 URL 路径关联起来。 9. 创建模板: 模板是 Django 中的 HTML 文件,用于呈现视图。你需要在 students/templates/students 目录中创建一个名为 student_list.html 的模板,用于显示学生列表。 10. 运行服务器: 最后,你可以运行以下命令来启动 Django 服务器:`python manage.py runserver` 这只是一个基本的概述,但它应该帮助你开始使用 Django 构建学生管理系统。如果你需要更详细的指导,请参考 Django 官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值