一、 CMDB后台管理

CMDB管理主要分为采集资产、API接口、后台管理。这里主要介绍CMDB后台管理。

- 采集资产
- API
- 后台管理- 资产列表- 业务线列表- 用户列表- 组列表...(每个功能都要实现增删改查功能)公共组件就是:删改查查:资产列表(CURD)可以做一个配置文件config:config = [{'q': 'id',}{'q': 'name',}]values_list = ['id', 'name']rerult = model.TB.object.filter(条件).values(*values_list)标配:配置+数据操作

为实现基本的后台管理功能,使用Django来实现。首先创建Django项目。

1、创建Django项目 autolist
创建Django项目autolist,及 app01,在settings.py中注册app01,并且设置静态文件夹。STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
设置完静态文件夹后,在项目文件夹下创建静态文件夹static,并将jQuery文件放到static文件夹下。2、 定义数据表结构,创建数据库
接下来在app01models.py中创建三张表,代码如下所示:
位置:app01models.py

from django.db import models
class UserInfo(models.Model):"""用户表"""name = models.CharField(max_length=32)age = models.IntegerField()class BusinessUnit(models.Model):"""业务线表"""name = models.CharField(max_length=32)class Server(models.Model):"""服务器表"""server_type_choices = ((1, 'WEB'),(2, '存储'),(3, '缓存'),)server_type = models.IntegerField(choices=server_type_choices, default=1)hostname = models.CharField(max_length=32)port = models.IntegerField()business_unit = models.ForeignKey('BusinessUnit', on_delete=None)user = models.ForeignKey('UserInfo', on_delete=None)

在命令行执行下面两个命令,在数据库中创建models.py文件中的表:python manage.py makemigrations
python manage.py migrate
3、 修改urls.py文件,添加需要的URL
这次使用CBV来实现代码,在autolisturls.py文件添加如下的URL:

from django.contrib import admin
from django.urls import path, re_path
from app01 import viewsurlpatterns = [path('admin/', admin.site.urls),re_path('^server.html/', views.ServerView.as_view()),re_path('^server-json.html/', views.ServerJsonView.as_view()),
]

4、 编写视图函数,实现主要功能,前端定制表头及表内容
在app01views.py 文件中写视图函数,主要的功能代码在这个 views.py 文件中。代码如下所示:

from django.shortcuts import render, HttpResponse
from django.views import View
from app01 import models
import jsonclass BaseResponse(object):def __init__(self):"""定义下面的属性是为了更好的封装并访问"""self.status = Trueself.data = Noneself.message = Noneclass ServerView(View):def get(self, request, *args, **kwargs):return render(request, 'server.html')class ServerJsonView(View):def get(self, request, *args, **kwargs):response = BaseResponse()try:# 获取要显示的列# 获取数据table_config = [            # table_config 是一个字典列表{'q': 'hostname',    # 键 q 对应的值就是数据库的字段名称'title': '主机名','display': 1,       # 通过设置 display 的值,让title的值是否要在页面上显示。0 不显示},{'q': 'port','title': '端口','display': 1,},{'q': 'business_unit_id','title': '业务线ID','display': 1,},{'q': 'business_unit__name',     # 通过双下划线跨表查询'title': '业务线名称','display': 1,},{'q': None,'title': '操作','display': 1,},]value_list = []                     # 创建数据库查询需要的字段信息for item in table_config:if item['q']:value_list.append(item['q'])    # 取到 table_config 这个字典列表的所有键为 q 的值data_list = models.Server.objects.values(*value_list)  # result是QuerySet类型:[{}, {},...]data_list = list(data_list)print(data_list)response.data = {'table_config': table_config, 'data_list': data_list,}except Exception as e:response.status = Falseresponse.message = str(e)return HttpResponse(json.dumps(response.__dict__))

在 views.py 文件中,主要定义的3个类BaseResponse、ServerView、ServerJsonView,其中 BaseResponse 类主要定义一些变量名,为了在代码中更好的进行封装。ServerView类就是对应的server.html这个URL。ServerJsonView类对应的是server-json.html这个URL。在ServerJsonView中的table_config这个字典列表中,键q对应的是数据库中的字段,通过后面的for循环,取出所有的键,然后用这些键去数据库中进行查询,查询到的结果是QuerySet类型,即字典列表类型,将查询到的结果传递到前端,前端获取相应信息进行显示。5、 编写模板文件server.html
这里通过server.html文件让查询到的结果在页面上显示,详细代码如下所示:

<body><table border="1"><thead id="thead"></thead><tbody id="tbody"></tbody></table><script src="/static/jquery1.12.4.js"></script><script>$(function () {init();});function init() {// 获取要显示的列// 获取数据$.ajax({url: '/server-json.html',type: 'GET',dataType: 'JSON',success: function(arg, a1, a2) {if(arg.status){     // views中的函数没有出错,执行下面的代码// 创建表格标题createTablehead(arg.data.table_config);createTablebody(arg.data.table_config, arg.data.data_list);}else{              // views中的函数如果出错,就在页面上显示一条消息alert(arg.message);}}});}function createTablehead(config) {console.log(config);var tr = document.createElement('tr');      // 创建tr标签$.each(config, function (k,v) {// 循环config,v 是字典if(v.display){var th = document.createElement("th");  // 创建th标签th.innerHTML = v.title;                 // th 标签添加值$(tr).append(th);                       // th 标签添加到tr标签中}});$("#thead").append(tr);                         // 把tr标签添加到thead标签中}function createTablebody(tableConfig, dataList) {/*dataList:[{'hostname': 'michael.com', 'port': 888}, {'hostname': 'python.org', 'port': 666}]*/$.each(dataList, function (k1, row) {// row = {'hostname': 'michael.com', 'port': 888}var tr = document.createElement('tr');       // 创建tr标签$.each(tableConfig, function (k2, configItem) {var td = document.createElement('td');      // 创建 td 标签td.innerHTML = row[configItem.q];$(tr).append(td);                           // td 标签添加到 tr 标签内});$("#tbody").append(tr);})}</script>
</body>

在运行这段HTML代码前,要先引入jQuery文件。在HTML代码中,init函数中使用ajax方式去请求 server-json.html 页面的内容,请求到的内容是JSON格式。请求成功后,将请求到的数据传递到 success 对应的函数,函数的 arg 参数就是用来接收请求成功后的数据。接着通过 createTablehead 函数和 createTablebody 函数分别创建表头和表体,将数据库查询到的内容在页面上显示。访问 http://127.0.0.1:8000/server.html/ 页面显示效果如下图1-1所示。

图1-1 主机管理页面显示效果

页面上显示的内容,完全由视图中的函数来控制,如果数据库有增加字段或者减少字段,通过修改视图中的 table_config 这个字典列表即可。其它的代码都不需要做变动。6、 封装自己的组件
在模板中的JS代码过长,可将JS代码进行封装成组件,之后进行调用即可。为此在autoliststatic目录下创建一个 michael-list.js的文件。
在封装组件的时候,需要考虑的问题:ajax中的URL已经写死;函数名可能与别的组件重复;公共的参数需要提取出来。为解决函数名
与变量名可能重复的问题,JS有一个自执行函数的功能可使用,使用方法是两个圆括号(()()),示例如下所示:(function(){my_code})();
在my_code中放入自己写的代码即可。但是自己写的代码中,如果有使用jQuery的话,还要注意引入jQuery。这样封装完后,下一个考虑的问题是怎样调用封装在自执行函数中的函数。这需要在自执行函数中传递参数jQuery,在自执行函数内部有一个 extend 函数可调用内部的函数,外部可通过extend直接调用其内部的函数。经过上述分析,michael-list.js 的代码如下所示:
位置:autoliststaticmichael-list.js

(function (jq) {var requestURL;function init() {// 获取要显示的列// 获取数据$.ajax({url: requestURL,type: 'GET',dataType: 'JSON',success: function(arg, a1, a2) {if(arg.status){     // views中的函数没有出错,执行下面的代码// 创建表格标题createTablehead(arg.data.table_config);createTablebody(arg.data.table_config, arg.data.data_list);}else{              // views中的函数如果出错,就在页面上显示一条消息alert(arg.message);}}});}function createTablehead(config) {console.log(config);var tr = document.createElement('tr');      // 创建tr标签$.each(config, function (k,v) {// 循环config,v 是字典if(v.display){var th = document.createElement("th");  // 创建th标签th.innerHTML = v.title;                 // th 标签添加值$(tr).append(th);                       // th 标签添加到tr标签中}});$("#thead").append(tr);                         // 把tr标签添加到thead标签中}function createTablebody(tableConfig, dataList) {/*dataList:[{'hostname': 'michael.com', 'port': 888}, {'hostname': 'python.org', 'port': 666}]*/$.each(dataList, function (k1, row) {// row = {'hostname': 'michael.com', 'port': 888}var tr = document.createElement('tr');       // 创建tr标签$.each(tableConfig, function (k2, configItem) {if(configItem.display){var td = document.createElement('td');      // 创建 td 标签td.innerHTML = row[configItem.q];$(tr).append(td);                           // td 标签添加到 tr 标签内}});$("#tbody").append(tr);})}jq.extend({'michael': function (url) {requestURL = url;init();}})
})(jQuery);

这时server.html文件修改后的代码如下所示:

<body><table border="1"><thead id="thead"></thead><tbody id="tbody"></tbody></table><script src="/static/jquery1.12.4.js"></script><script src="/static/michael-list.js"></script><script>$(function () {$.michael('/server-json.html');       // 调用自己封装的组件});</script>
</body>

7、使用自己封装的组件快速开发一个显示业务线的页面
现在如果要创建显示业务线的页面显示,也可以快速完成。先在templates目录下创建 business.html 文件,该文件的代码由 server.html文件的复制过来。只需要将调用自己封装的组件时传递不同的URL即可。例如下面这行代码中传递的URL:
$.michael('/business-json.html');
还需要在 autolisturls.py 文件中添加两个URL:re_path('^business.html/', views.BusinessView.as_view()),
re_path('^business-json.html/', views.BusinessJsonView.as_view()),

接着在 app01views.py 文件增加两个类 BusinessView 和 BusinessJsonView,这两个类的代码如下所示:

class BusinessView(View):def get(self, request, *args, **kwargs):return render(request, 'business.html')class BusinessJsonView(View):def get(self, request, *args, **kwargs):response = BaseResponse()try:table_config = [            # table_config 是一个字典列表{'q': 'id',          # 键 q 对应的值就是数据库的字段名称'title': 'ID','display': 1,       # 通过设置 display 的值,让title的值是否要在页面上显示。0 不显示},{'q': 'name','title': '业务线名称','display': 1,},{'q': None,'title': '操作','display': 1,},]value_list = []                     # 创建数据库查询需要的字段信息for item in table_config:if item['q']:value_list.append(item['q'])    # 取到 table_config 这个字典列表的所有键为 q 的值data_list = models.BusinessUnit.objects.values(*value_list)  # result是QuerySet类型:[{}, {},...]data_list = list(data_list)print(data_list)response.data = {'table_config': table_config, 'data_list': data_list,}except Exception as e:response.status = Falseresponse.message = str(e)return HttpResponse(json.dumps(response.__dict__))

在 BusinessJsonView 类,要特别注意修改了 models.BusinessUnit.objects.values(*value_list) 这行代码中的表名。现在访问 http://127.0.0.1:8000/business.html/ 就能看到业务线名称的页面。这就简单快速的完成了业务线页面的开发。8、前端插件定制之定制td内容及属性
现在给前端的td标签定制要显示的内容及属性,通过修改views.py文件中的 table_config 参数,在这个参数中添加配置即可。在前端通过循环这个配置参数,获取到相应的键值,就能做出对应的处理。修改后的views.py文件和michael-list.js文件代码如下所示:
位置:app01views.py

from django.shortcuts import render, HttpResponse
from django.views import View
from app01 import models
import jsonclass BaseResponse(object):def __init__(self):"""定义下面的属性是为了更好的封装并访问"""self.status = Trueself.data = Noneself.message = Noneclass ServerView(View):def get(self, request, *args, **kwargs):return render(request, 'server.html')class ServerJsonView(View):def get(self, request, *args, **kwargs):response = BaseResponse()try:# 获取要显示的列# 获取数据table_config = [            # table_config 是一个字典列表{'q': 'id','title': '主机名','display': 0,'text': {},'attr': {},},{'q': 'hostname',    # 键 q 对应的值就是数据库的字段名称'title': '主机名','display': 1,       # 通过设置 display 的值,让title的值是否要在页面上显示。0 不显示'text': {'content': '{m}', 'kwargs': {'m': '@hostname'}},'attr': {'k1': '@hostname', 'k2': 'v2'},},{'q': 'port','title': '端口','display': 1,'text': {'content': '{m}', 'kwargs': {'m': '@port'}},'attr': {'k1': '@port', 'k2': 'v2'},},{'q': 'business_unit_id','title': '业务线ID','display': 1,'text': {'content': '{m}', 'kwargs': {'m': '@business_unit_id'}},'attr': {'k1': '@business_unit_id', 'k2': 'v2'},},{'q': 'business_unit__name',     # 通过双下划线跨表查询'title': '业务线名称','display': 1,'text': {'content': '{m}', 'kwargs': {'m': '@business_unit__name'}},'attr': {'k1': '@business_unit__name', 'k2': 'v2'},},{'q': None,'title': '操作','display': 1,'text': {'content': '<a href="/server-detail-{m}.html">查看详细</a>', 'kwargs': {'m': '@id'}},'attr': {'k1': '@id', 'k2': 'v2'},},]value_list = []                     # 创建数据库查询需要的字段信息for item in table_config:if item['q']:value_list.append(item['q'])    # 取到 table_config 这个字典列表的所有键为 q 的值data_list = models.Server.objects.values(*value_list)  # result是QuerySet类型:[{}, {},...]data_list = list(data_list)print(data_list)response.data = {'table_config': table_config, 'data_list': data_list,}except Exception as e:response.status = Falseresponse.message = str(e)return HttpResponse(json.dumps(response.__dict__))

位置:autoliststaticmichael-list.js

(function (jq) {var requestURL;// 为字符串创建format方法,用于字符串格式化/** 控制台使用方法:v = "{id}michael{name}",v.format({'id': 123, 'name':'root'})* 输出:"123michaelroot"* */String.prototype.format = function (args) {return this.replace(/{(w+)}/g, function (g, i) {return args[i];});};function init() {// 获取要显示的列// 获取数据$.ajax({url: requestURL,type: 'GET',dataType: 'JSON',success: function(arg, a1, a2) {if(arg.status){     // views中的函数没有出错,执行下面的代码// 创建表格标题createTablehead(arg.data.table_config);createTablebody(arg.data.table_config, arg.data.data_list);}else{              // views中的函数如果出错,就在页面上显示一条消息alert(arg.message);}}});}function createTablehead(config) {//console.log(config);var tr = document.createElement('tr');      // 创建tr标签$.each(config, function (k,v) {// 循环config,v 是字典if(v.display){var th = document.createElement("th");  // 创建th标签th.innerHTML = v.title;                 // th 标签添加值$(tr).append(th);                       // th 标签添加到tr标签中}});$("#thead").append(tr);                         // 把tr标签添加到thead标签中}function createTablebody(tableConfig, dataList) {/*dataList:[{'hostname': 'michael.com', 'port': 888}, {'hostname': 'python.org', 'port': 666}]'text': {'content': '{n}-{m}', 'kwargs': {'n': 'hostname', 'm': '@hostname'}}*/$.each(dataList, function (k1, row) {// row = {'hostname': 'michael.com', 'port': 888}var tr = document.createElement('tr');       // 创建tr标签$.each(tableConfig, function (k2, configItem) {if(configItem.display){/** 'text': {'content': '{n}-{m}', 'kwargs': {'n': 'hostname', 'm': '@hostname'}}* */var td = document.createElement('td');      // 创建 td 标签//td.innerHTML = row[configItem.q];//configItem.text.contentvar kwargs = {};$.each(configItem.text.kwargs, function (key, value) {if(value.startsWith('@')){var temp = value.substring(1, value.length);kwargs[key] = row[temp]     // 需要在数据库查询的字段}else{kwargs[key] = value         // 不需要在数据库查询的值}});td.innerHTML = configItem.text.content.format(kwargs);$.each(configItem.attr, function (key, value) {if(value.startsWith('@')){var temp = value.substring(1, value.length);td.setAttribute(key, row[temp]);}else{td.setAttribute(key, value);}});$(tr).append(td);                           // td 标签添加到 tr 标签内}});$("#tbody").append(tr);})}jq.extend({'michael': function (url) {requestURL = url;init();}})
})(jQuery);

现在不需要修改server.html文件的代码,访问 http://127.0.0.1:8000/server.html/ 页面同样能正常显示,并且给td标签都添加了属性,以及td标签要显示的内容。这些都是在vews.py文件中的 table_config 参数定制的。显示效果如图1-2所示。

图1-2 前端td标签定制内容及属性

cmdb python 采集虚拟机_Python编程(三十四):CMDB后台管理、封装自定义JS组件、前端td标签定制显示内容及属性...相关推荐

  1. python图形界面化编程GUI(一)窗口管理和常用的组件(Label、Button、Entry)

    GUI GUI(Graphics User Interface)图形用户界面编程.我们可以通过 python 提供的丰富的组件,快速的实现使用图形的界面和用户交互. GUI 编程类似于"搭积 ...

  2. cmdb python 采集虚拟机_CMDB学习之八,完成所有资产采集信息的收集

    #!/usr/bin/env python#-*- coding:utf-8 -*- importos,refrom .base importBasePluginfrom lib.response i ...

  3. [Python从零到壹] 三十五.图像处理基础篇之OpenCV绘制各类几何图形

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  4. [Python从零到壹] 三十九.图像处理基础篇之图像几何变换(镜像仿射透视)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  5. [Python从零到壹] 三十六.图像处理基础篇之图像算术与逻辑运算详解

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  6. [Python从零到壹] 三十八.图像处理基础篇之图像几何变换(平移缩放旋转)

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  7. [Python从零到壹] 五十四.图像增强及运算篇之局部直方图均衡化和自动色彩均衡化处理

    首先,祝大家教师节和中秋节快乐! 欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文 ...

  8. [Python从零到壹] 六十四.图像识别及经典案例篇之图像傅里叶变换和傅里叶逆变换详解

    祝大家新年快乐,阖家幸福,健康快乐! 欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所 ...

  9. Linux的基本学习(十四)——进程管理(下)与SELinux

    Linux的基本学习(十四)--进程管理(下)与SELinux 前言 进程这部分内容真是不少,来,我们继续跟着鸟哥学习. 特殊文件与进程 具有SUID/SGID权限的命令执行状态 SUID的权限其实与 ...

最新文章

  1. struts2 action之间参数的传递
  2. python语言自学-python语言系统学习(四)
  3. JBOSS配置系统应用的端口号
  4. 二叉苹果树(树型DP+背包)
  5. 初学者计算机_初学者极客:如何在计算机上重新安装Windows
  6. Ue4.20 安卓开发配置及Android Studio 调试ue安卓工程
  7. 计算机网络技术期中,计算机网络技术基础期中试卷
  8. android 动态单选,添加单选按钮动态︰android
  9. PHP 中检查是否关联数组(多维数组)的方法 (UPDATE!)
  10. css鼠标移上去向上移动,css3鼠标移动图片上移效果
  11. Windows下安装dilb解决方法
  12. diskgenius创建efi分区_怎么创建efi系统分区?efi系统分区创建教程
  13. 博网即时通讯软件的设计与实现(附源码+课件+数据库+资料)
  14. matlab2016自带ga,[转载]MATLAB中自带遗传算法函数GA的用法
  15. Core Data概述
  16. Python解释器的选择,初学者必看
  17. extjs调试错误 TypeError:p is null 或 TypeError: el is null
  18. IPU到底是个什么鬼?
  19. 一位明星证券客户经理的十年辛酸史--俊材有话说
  20. 编写QQ显IP外挂插件及原理分析

热门文章

  1. 分屏总屏计算机电缆,分屏加总屏电缆DJYVP计算机电缆14x2x0.75
  2. map的key可以试一个数组吗?_二维数组的 DP
  3. 以后可得记住了--Python笔试面试题小结
  4. web前端篇:html基础知识
  5. 使用Java实现发送email邮件
  6. LeetCode(40):组合总和 II
  7. 【转】Maven实战(八)---模块划分
  8. 最近总是淡淡的····
  9. js添加事件、移除事件、阻止冒泡、阻止浏览器默认行为等写法(兼容IE/FF/CHROME) 转载...
  10. java url工具_UrlTool官方版|UrlTool (java Url转换工具)下载v1.1-乐游网软件下载