「django开发」CMDB实验————12、数据展示页设计(自用)

一、login页

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CMDB登录</title>
    <link rel="icon" href="{% static 'img/web_logo.png' %}" type="image/x-icon">
    <link rel="stylesheet" href="{% static 'css/login.css'%}">
    <script src="{% static 'js/login.js' %}"></script>
</head>
<body>
    <div id="attention">
        <img src="{% static 'img/网站设置.png'%}">
        <b><i style="color: #1296db">欢迎来到CMDB管理中心</i></b>
        <a href="/register/" id="register">申请账户</a>
    </div>
    <div style="height: 100vh" id="back"></div>

    <p id="unLoginNotice">{{ unLogin }}</p>

    <form method="post" id="loginBlock">
        <img src="{% static 'img/管理员_角色管理.png' %}" alt="图片丢失">
        <span id="loginTitle">
            管理员登录
        </span>
        <input type="text" placeholder="请输入管理员账号" name="username">
        <br>
        <input type="password" placeholder="请输入密码" name="password">
        <br>
        <span style="font-size: 10px;color: red">{{ notice }}</span>
        <br>
        <input type="submit" id="sub" title="登录" value="登录">
    </form>
</body>
</html>
*{
    margin: 0;
    padding: 0;
}
body{
    background-image: url('../img/bgc.jpg');
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
}
#attention{
    height: 40px;
    line-height: 40px;
    font-size: 20px;
    align-items: center;
    padding-left: 60px;
    overflow: hidden;
}
#attention>img{
    position: absolute;
    top: 6px;
    left: 20px;
    height: 30px;
    width: 30px;
}
#register{
    font-size: 10px;
    margin-left: 70%;
    color: #B0BED2;
}
#unLoginNotice{
    position: fixed;
    top: 20%;
    left: 45%;
    color: red;
    font-size: 30px;
}
form{
    border-radius: 5px;
    border: 1px solid grey;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 400px;
    padding: 10px;
    padding-right: 20px;
    align-content: center;
    background-color: white;
}
form>img{
    display: inline-block;
    height: 20px;
    width: 20px;
}
#loginTitle{
    display: inline-block;
    color: #1296db;
    position: relative;
    top: -4px;
    left: 5px;
}
input{
    border-radius: 5px;
    margin: 5px 0;
    width: 100%;
    height: 30px;
    line-height: 30px;
    padding-left: 5px;
    border: 1px solid lightgrey;
}
#sub{
    width: 405px;
}
#subImg{
    height: 15px;
    width: 15px;
}
window.onload = function (){
    //获取非法跳转提示信息。
    const unLoginNotice = document.getElementById('unLoginNotice');
    //获取输入表单。
    const loginBlock = document.getElementById('loginBlock');
    //当鼠标点击表单时,提示信息消失。
    loginBlock.addEventListener('click',function (){
        unLoginNotice.style.display = 'none';
    })
}

二、home页

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CMDB管理</title>
    <link rel="icon" href="{% static 'img/web_logo.png' %}" type="image/x-icon">
    <link rel="stylesheet" href="{% static 'css/home.css' %}">
    <script src="{% static 'js/home.js' %}"></script>
</head>
<body>
    <div id="attention">
        <img src="{% static 'img/网站设置.png'%}">
        <b><i style="color: #1296db">欢迎{{ username }}来到CMDB管理中心</i></b>
    </div>

    <div id="nav"><img src="{% static 'img/工作台.png' %}"></div>
    <div id="dockersData">
        <img src="{% static 'img/卫星.png' %}" class="leftImg">
        <a href="#">容器状态中心</a>
    </div>
    <div id="processData">
        <img src="{% static 'img/卫星.png' %}" class="rightImg">
        <a href="#">进程状态中心</a>
    </div>
    <div id="verCodeCenter">
        <img src="{% static 'img/卫星.png' %}" class="leftImg">
        <a href="#">核验码管理中心</a>
    </div>
    <div id="accountCenter">
        <img src="{% static 'img/卫星.png' %}" class="rightImg">
        <a href="#">账户管理中心</a>
    </div>
</body>
</html>
*{
    margin: 0;
    padding: 0;
}
body{
    background-image: url('../img/bgc.jpg');
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
}
#attention{
    height: 40px;
    line-height: 40px;
    font-size: 20px;
    align-items: center;
    padding-left: 60px;
    overflow: hidden;
}
#attention>img{
    position: absolute;
    top: 6px;
    left: 20px;
    height: 30px;
    width: 30px;
}
#nav{
    display: block;
    height: 400px;
    width: 400px;
    text-align: center;
    border-radius: 400px;
    border: 1px solid black;
    position: relative;
    left: 500px;
    top: 130px;
    background-image: url('../img/adminBgc.jpg');
    background-position: center center;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 1);
    filter: brightness(0.9);
}
#nav>img{
    margin-top: 100px;
    width: 200px;
    height: 200px;
}
a{
    color: gold;
}
a:hover{
    color: red;
}
#dockersData{
    align-items: center;
    font-size: 30px;
    position: absolute;
    display: none;
    height: 200px;
    line-height: 200px;
    width: 300px;
    border-radius: 20px;
    top: 120px;
    left: 60px;
}
#processData{
    align-items: center;
    font-size: 30px;
    position: absolute;
    display: none;
    height: 200px;
    line-height: 200px;
    width: 500px;
    border-radius: 20px;
    top: 130px;
    left: 870px;
}
#verCodeCenter{
    align-items: center;
    font-size: 30px;
    position: absolute;
    display: none;
    height: 200px;
    line-height: 200px;
    width: 300px;
    border-radius: 20px;
    top: 400px;
    left: 60px;
}
#accountCenter{
    align-items: center;
    font-size: 30px;
    position: absolute;
    display: none;
    height: 200px;
    line-height: 200px;
    width: 500px;
    border-radius: 20px;
    top: 410px;
    left: 870px;
}
.leftImg{
    transform: scaleX(-1);
    width: 30px;
}
.rightImg{
    width: 30px;
}
window.onload = function (){
    //获取导航球
    const nav = document.getElementById('nav');
    //获取子模块。
    const dockersData = document.getElementById('dockersData');
    const processData = document.getElementById('processData');
    const verCodeCenter = document.getElementById('verCodeCenter');
    const accountCenter = document.getElementById('accountCenter');
    //定义休眠函数。
    function sleep(ms) {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
    //设置导航球鼠标移入时向左移动,子模块显示。
    nav.addEventListener("mouseover", async function (event) {
        nav.style.transition = "transform 0.3s ease-in-out";
        nav.style.transform = "translateX(-100px)";

        await sleep(500); // 延迟 500 毫秒(0.5秒)

        dockersData.style.display = 'block';
        processData.style.display = 'block';
        verCodeCenter.style.display = 'block';
        accountCenter.style.display = 'block';
    });
    // 设置导航块鼠标移出时恢复原设置。
    nav.addEventListener("mouseout", async function (event) {
        await sleep(10000); // 延迟 10000 毫秒(10秒)
        dockersData.style.display = 'none';
        processData.style.display = 'none';
        verCodeCenter.style.display = 'none';
        accountCenter.style.display = 'none';

        nav.style.transform = "translateX(0)";
    });
}

三、register页

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>申请管理员账号</title>
    <link rel="icon" href="{% static 'img/web_logo.png' %}" type="image/x-icon">
    <link rel="stylesheet" href="{% static 'css/register.css' %}">
</head>
<body>
    <div id="attention">
        <img src="{% static 'img/网站设置.png'%}">
        <b><i style="color: #1296db">欢迎来到CMDB管理中心</i></b>
        <a href="/" id="login">登录</a>
    </div>
    <form method="post">
        <img src="{% static 'img/管理员_角色管理.png' %}" alt="图片丢失">
        <span id="registerTitle">申请账户</span>
        <input type="text" placeholder="请输入姓名" class="inputBlock" name="name">
        <input type="text" placeholder="请输入用户名" class="inputBlock" name="username">
        <span class="notices">{{ user_notice }}</span>
        <input type="password" placeholder="请输入密码" class="inputBlock" name="password">
        <span class="notices">{{ psw_notice }}</span>
        <input type="password" placeholder="再次输入密码" class="inputBlock" name="verpwd">
        <span class="notices">{{ psw_notice }}</span>
        <input type="text" placeholder="请输入邮箱" class="inputBlock" name="email">
        <span class="notices">{{ email_notice }}</span>
        <input type="text" placeholder="请输入核验码" class="inputBlock" name="vercode">
        <span class="notices">{{ ver_notice }}</span>
        <br>
        <input type="submit" value="注册" class="inputBlock" name="reg">
    </form>
</body>
</html>
*{
    padding: 0;
    margin: 0;
}
body{
    background-image: url('../img/bgc.jpg');
    background-repeat: no-repeat;
    background-size: cover;
    background-position: center center;
}
#attention{
    height: 40px;
    line-height: 40px;
    font-size: 20px;
    align-items: center;
    padding-left: 60px;
    overflow: hidden;
}
#attention>img{
    position: absolute;
    top: 6px;
    left: 20px;
    height: 30px;
    width: 30px;
}
#login{
    font-size: 10px;
    margin-left: 80%;
}
form{
    background-color: white;
    border: 1px lightgrey solid;
    width: 300px;
    margin: 200px auto;
    padding: 5px 8px 5px 5px;
}
form>img{
    display: inline-block;
    height: 20px;
    width: 20px;
}
#registerTitle{
    display: inline-block;
    color: #1296db;
    position: relative;
    top: -4px;
    left: 5px;
}
.notices{
    font-size: 10px;
    color: red;
}
.inputBlock{
    display: block;
    height: 20px;
    line-height: 20px;
    width: 100%;
    margin: 5px 0;
}

四、view.py

from django.shortcuts import render, redirect
from web.tools import searchData
import os
import django
import re
import ast

# 环境配置
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'CMDB.settings')
django.setup()


# Create your views here.
def login(request):
    """
    登录页面
    :param request:
    :return: 账号验证无误则进入管理首页,有误则包含警告信息返回当前页
    """
    unLogin = ''
    # 调用数据库查询方法
    rows = searchData.searchContents('users')
    # 将数据库中获取的元组转为字典
    users = {}
    for row in rows:
        users[row[0]] = row[1]

    # 根据页面的访问方式进行响应
    if request.method == 'GET':
        if 'unLogin' in request.session:
            unLogin = request.session['unLogin']
        return render(request, 'login.html', {'unLogin': unLogin})
    else:
        username = request.POST.get('username')
        password = request.POST.get('password')

        if username in users and password == users[username]:
            # 使用会话传递用户名
            request.session['username'] = username
            return redirect('/home')

        return render(request, 'login.html', {'notice': '管理员账号或密码输入错误', 'unLogin': unLogin})


def home(request):
    """
    :param request:
    :return: 首页
    """
    # 获取users表中所有信息,判断跳转时携带的用户名是否正确。
    # 调用数据库查询方法
    rows = searchData.searchContents('users')
    # 将数据库中获取的元组转为字典
    users = {}
    for row in rows:
        users[row[0]] = row[1]

    # 获取session中存放的用户名
    username = request.session.get('username')

    if username not in users:
        request.session['unLogin'] = '您还未登录!'
        return redirect('/login')

    # 清除session防止影响其他功能
    # request.session.flush()

    # 获取最新文件内容
    os.system(r"C:\Users\12269\PycharmProjects\CMDB\web\tools\getClientData.py")

    # 获取'web/clientData/dockerStatus.txt'内容,并进行过滤操作。
    dockerStatus = []
    try:
        with open('web/clientData/dockerStatus.txt', 'r') as file:
            # 将文件中内容转化成列表
            for line in file:
                data = ast.literal_eval(line)
                dockerStatus.append(data)
            # 删除每个子列表的第一个元素
            for sublist in dockerStatus:
                del sublist[0]
    except FileNotFoundError:
        print('文件 web/clientData/dockerStatus.txt 不存在!')

    # 将dockerStatus列表中存储的信息传输至数据表
    from web.models import DockerStatus

    # 清空数据表
    DockerStatus.objects.all().delete()
    # 插入数据
    for i in range(0, len(dockerStatus)):
        obj = DockerStatus.objects.create(**{'name': dockerStatus[i][0], 'status': dockerStatus[i][1]})
        obj.save()
    # 从数据库中获取web_dockerstatus表的数据
    rows = searchData.searchContents('web_dockerstatus')
    dockerStatus = {}
    for row in rows:
        dockerStatus[row[1]] = row[2]

    # 获取'web/clientData/allDockerStatus.txt'内容
    servicesStatus = ''
    try:
        with open('web/clientData/allServicesStatus.txt', 'r') as file:
            content = file.readlines()
            servicesStatus = [line.replace('\n', '') for line in content]  # 去除\n
    except FileNotFoundError:
        print('文件 web/clientData/allDockerStatus.txt 不存在!')

    # 筛选allServicesStatus.txt中的有效数据,并存入web_allServicesStatus表中

    from web.models import AllServicesStatus
    # 清空数据表
    AllServicesStatus.objects.all().delete()

    did = ''
    name = ''

    for row in servicesStatus:
        user = ''
        pid = ''
        ppid = ''
        cpu = ''
        elapsed = ''
        tty = ''

        if 'Container ID' in row:
            did = row[-12:]  # 获取容器ID

        if 'Container Name' in row:
            name = row[15:]  # 获取容器名称

        if 'USER' in row:
            continue  # 当遍历到表头行时跳过该行

        if 'has no running processes' in row:  # 当容器中不存在进程,则状态字段置空
            obj = AllServicesStatus.objects.create(**{'did': did,
                                                      'name': name,
                                                      'user': user,
                                                      'pid': pid,
                                                      'ppid': ppid,
                                                      'cpu': cpu,
                                                      'elapsed': elapsed,
                                                      'tty': tty})
            obj.save()

        if 'pts' in row or '?' in row:
            tempStatusList = re.split(r"\s+", row.strip())  # 按空格拆分行
            print(tempStatusList)
            user = tempStatusList[1]  # 获取服务用户
            pid = tempStatusList[2]  # 获取服务pid
            ppid = tempStatusList[3]  # 获取服务ppid
            cpu = tempStatusList[4]  # 获取服务cpu使用率
            elapsed = tempStatusList[5]  # 获取服务运行时间
            tty = tempStatusList[6]  # 获取服务tty

            # 填入数据
            obj = AllServicesStatus.objects.create(**{'did': did,
                                                      'name': name,
                                                      'user': user,
                                                      'pid': pid,
                                                      'ppid': ppid,
                                                      'cpu': cpu,
                                                      'elapsed': elapsed,
                                                      'tty': tty})
            obj.save()

        # 从数据库获取数据。
        servicesStatus = searchData.searchContents('web_allServicesStatus')
    return render(request, 'home.html',
                  {'username': username, 'dockerStatus': dockerStatus, 'servicesStatus': servicesStatus})


def register(request):
    """
    注册页面
    :param request:
    :return: 注册信息无误返回登录界面,有误则包含警告信息返回当前页
    """
    if request.method == 'GET':
        return render(request, 'register.html')
    else:
        # 获取注册信息
        name = request.POST.get('name')
        username = request.POST.get('username')
        password = request.POST.get('password')
        verpwd = request.POST.get('verpwd')
        email = request.POST.get('email')
        vercode = request.POST.get('vercode')

        # 警告信息
        user_notice = ''
        psw_notice = ''
        ver_notice = ''
        email_notice = ''

        # 正则表达式
        user_pattern = r'^[a-zA-Z0-9_]+$'
        psw_pattern = r'^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[@#$%^&+=])(?!.*\s).{8,}$'
        email_pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'

        # 核验用户名
        if not re.match(user_pattern, username):
            user_notice = '用户名仅可由数字字母下划线组成'

        # 从数据库中获取所有用户名,当前用户名存在时提示重复并重新输入
        rows = searchData.searchContents('users')
        if username in rows:
            user_notice = '用户名不可重复'

        # 核验密码,当两次密码输入相同且不为空时通过密码核验
        if not (password == verpwd and password and re.match(psw_pattern, password)):
            psw_notice = '请重新输入密码'

        # 核验邮箱
        if not re.match(email_pattern, email):
            email_notice = '邮箱格式有误'

        # 验证核验码,从数据库中查询核验码是否存在且未被使用
        rows = searchData.searchContents('web_vercode')

        # 设置验证信号,初始为False,当核验成功则置为True
        flag = False
        for row in rows:
            if row[1] == vercode and row[2] == 'False':
                # 如果核验码有效,则将该核验码失效
                from web.models import VerCode
                obj = VerCode.objects.get(id=row[0])
                obj.status = 'True'
                obj.save()
                # 修改验证信号
                flag = True
                break

        # 无效核验码时
        if not flag:
            ver_notice = '核验码无效'

        # 当两个警告信息有一个不为空时,则说明输入有误
        if psw_notice or ver_notice:
            return render(request, 'register.html',
                          {'user_notice': user_notice, 'psw_notice': psw_notice, 'email_notice': email_notice,
                           'ver_notice': ver_notice, })

        # 信息输入无误后,将注册信息传入申请表中,并返回登录界面
        from web.models import Candidate

        obj = Candidate.objects.create(
            **{'name': name, 'username': username, 'password': password, 'email': email, 'verCode': vercode})
        obj.save()

        # 所有信息处理完毕,返回登录页
        return redirect('/login')

有一些我自己写的脚本没有粘在此文档中,有需要可以自行查看往期文章,还有一些图片素材我没有放出,大家可以根据自己喜好查找素材。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值