Django最强大的部分之一是自动管理界面。它从模型中读取元数据,以提供一个快速的,以模型为中心的界面,受信任的用户可以在其中管理您网站上的内容。管理员的建议用法仅限于组织的内部管理工具。它并非旨在构建您的整个前端。
Django Admin 简单配置
settings.py
LANGUAGE_CODE = 'zh-hans' | |
TIME_ZONE = 'Asia/Shanghai' |
models.py
from django.db import models | |
import sqlite3 | |
from django.utils.html import format_html | |
STATUS_CHOICES = (('d', '正常'),('p', '警告'),('w', '损坏'),) | |
class HostDB(models.Model): | |
id = models.AutoField(primary_key=True) | |
hostname = models.CharField(max_length=64,verbose_name="主机名称") | |
hostaddr = models.TextField(max_length=64,verbose_name="主机地址") | |
hostCPU = models.CharField(max_length=64,verbose_name="主机CPU") | |
hostMEM = models.CharField(max_length=64,verbose_name="主机内存") | |
DataTime = models.DateTimeField(verbose_name="主机当前时间") | |
hostUser = models.CharField(max_length=64,verbose_name="负责人") | |
hostStats = models.CharField(max_length=1,choices=STATUS_CHOICES,verbose_name="状态") | |
def __str__(self): | |
return self.hostname | |
# 自定义方法,主要负责给主机标注颜色 | |
def Status(self): | |
if self.hostStats == 'd': | |
format_td = format_html('<span style="padding:2px;background-color:green;color:white">正常</span>') | |
elif self.hostStats == 'p': | |
format_td = format_html('<span style="padding:2px;background-color:yellow;color:black">警告</span>') | |
elif self.hostStats == 'w': | |
format_td = format_html('<span style="padding:2px;background-color:red;color:white">损坏</span>') | |
return format_td | |
Status.short_description = "当前状态" |
admin.py
from django.contrib import admin | |
from MyWeb.models import * | |
# 必须继承ModelAdmin基类,才可以调整参数,HostDB则是你的表的名称 | |
class MyAdmin(admin.ModelAdmin): | |
admin.site.site_title="自动化后台管理" | |
admin.site.site_header = "Django 自动化运维" | |
# list_display = 你需要展示的字段应该写在这里,此处是数据库中的字段 | |
list_display = ("hostname","hostaddr","hostCPU","hostMEM","DataTime","hostUser","Status") | |
# search_fields = 用于添加一个搜索框,此处以hostaddr作为查询条件 | |
search_fields = ("hostaddr",) | |
# list_filter = 设置一个过滤器,此处是以hostname作为过滤条件 | |
list_filter = ("hostname",) | |
# ordering = 设置一个排序条件,此处是以id作为排序依据 | |
ordering = ("id",) | |
#list_per_page = 设置每页显示多少条记录,默认是100条 | |
list_per_page = 10 | |
#list_editable = 设置默认可编辑字段 | |
#list_editable = ("DataTime",) | |
# date_hierarchy = 显示详细时间分层筛选 | |
date_hierarchy = 'DataTime' | |
# readonly_fields = 可以设置只读字段,就是无法修改的字段 | |
readonly_fields = ("hostCPU","hostMEM",) | |
python manage.py makemigrations | |
python manage.py migrate | |
python manage.py createsuperuser |
效果如下。
另外找到一个不错的主题
pip install simpleui | |
vim settings.py | |
INSTALLED_APPS = [ | |
'simpleui', | |
'django.contrib.admin', | |
'myweb.apps.MywebConfig', | |
] | |
STATIC_URL = '/static/' | |
STATICFILES_DIRS = [ | |
os.path.join(BASE_DIR, "static"), | |
] |
定制主机管理菜单
vim settings.py | |
LANGUAGE_CODE = 'zh-hans' | |
TIME_ZONE = 'Asia/Shanghai' | |
apps.py | |
from django.apps import AppConfig | |
class MywebConfig(AppConfig): | |
name = 'MyWeb' | |
verbose_name = "服务器集群" |
models.py
from django.db import models | |
from django.utils.html import format_html | |
STATUS_CHOICES = (('d', '正常'),('p', '警告'),('w', '损坏'),) | |
class HostInfo(models.Model): | |
id = models.AutoField(primary_key=True) | |
HostName = models.CharField(max_length=64,verbose_name="主机名") | |
HostAddr = models.CharField(max_length=64,verbose_name="主机IP") | |
HostModel = models.CharField(max_length=64,verbose_name="设备型号") | |
HostCPU = models.CharField(max_length=64,verbose_name="主机CPU") | |
HostMem = models.CharField(max_length=64,verbose_name="主机内存") | |
HostDisk = models.CharField(max_length=64,verbose_name="主机磁盘") | |
HostSys = models.CharField(max_length=64,verbose_name="操作系统") | |
HostZone = models.CharField(max_length=64,verbose_name="区域") | |
DataTime = models.DateField(max_length=64,verbose_name="统计时间") | |
HostPeple = models.CharField(max_length=64, verbose_name="负责人") | |
HostStats = models.CharField(max_length=1,choices=STATUS_CHOICES,verbose_name="状态") | |
def __str__(self): | |
return self.HostName | |
# 用于给本表指定一个别名 | |
class Meta(): | |
verbose_name = "Web前台集群" | |
verbose_name_plural= "Web前台集群" | |
# 自定义方法,主要负责给主机标注颜色 | |
def Status(self): | |
if self.HostStats == 'd': | |
format_td = format_html('<span style="padding:2px;background-color:green;color:white">正常</span>') | |
elif self.HostStats == 'p': | |
format_td = format_html('<span style="padding:2px;background-color:yellow;color:black">警告</span>') | |
elif self.HostStats == 'w': | |
format_td = format_html('<span style="padding:2px;background-color:red;color:white">损坏</span>') | |
return format_td | |
Status.short_description = "状态" |
admin.py
from django.contrib import admin | |
from MyWeb.models import * | |
# 必须继承ModelAdmin基类,才可以调整参数,HostDB则是你的表的名称 | |
class MyAdmin(admin.ModelAdmin): | |
admin.site.site_title="自动化后台管理" | |
admin.site.site_header = "Django 自动化运维" | |
# list_display = 你需要或者想要展示在页面中的字段 | |
list_display = ("HostName","HostAddr","HostModel","HostCPU","HostMem","HostDisk","HostSys","HostZone","DataTime","HostPeple","Status") | |
# search_fields = 添加搜索功能,并以HostName作为搜索条件 | |
search_fields = ("HostName",) | |
# ordering = 设置以HostAddr作为排序条件 | |
ordering = ("HostAddr",) | |
# list_per_page = 设置每页显示的字段数 | |
list_per_page = 10 |
自定义页面功能
在templates中新建一个名称为lyshark.html的文件
{% extends "admin/base_site.html" %} | |
{% load i18n static %} | |
{% load static %} | |
{% block title %}{{ site_title|default:_('Django site admin') }}{% endblock %} | |
{% block content %} | |
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script> | |
<script> | |
$(".breadcrumbs").append(" <a href=\"/admin/\">仪表盘</a>"); | |
$(".breadcrumbs").append(" <a href=\"/admin/\">主机监控</a>"); | |
$(".breadcrumbs").append(" <a href=\"/admin/\">命令执行</a>"); | |
$(".breadcrumbs").append(" <a href=\"/admin/\">图表绘制</a>"); | |
$(".breadcrumbs").append(" <a href=\"/admin/\">批量CMD</a>"); | |
</script> | |
<form action="/lyshark/" method="post"> | |
用户:<input type="text" value="text"> | |
密码:<input type="text" value="text"> | |
<input type="text" value="text"> | |
<input type="text" value="text"> | |
<input type="submit" value="提交表单"> | |
</form> | |
{% endblock %} |
接着在view.py中增加一条视图函数
from django.shortcuts import render | |
from django.contrib.auth.decorators import login_required | |
def lyshark(request): | |
return render(request,"lyshark.html") |
最后别忘了在urls.py里面添加映射记录.
from MyWeb import views | |
urlpatterns = [ | |
path('admin/', admin.site.urls), | |
path("lyshark/",views.lyshark) | |
] |
上方添加了装饰器,函数,只有用户登陆后才可以访问到定制页面,如果没有登陆则提示需要登陆,这样更加灵活了。
添加各种标志
添加已过期标志: 判断当前时间是否与数据库时间一致,并显示过期状态.
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
class MyAdmin(admin.ModelAdmin): | |
list_display = ("id","date","Status") | |
# name: models.py | |
from django.db import models | |
from django.utils.html import format_html | |
import datetime | |
class HostDB(models.Model): | |
id = models.AutoField(primary_key=True) | |
date = models.CharField(max_length=64) | |
def Status(self): | |
NowData = datetime.date.today() | |
if self.date >= str(NowData): | |
ret = "未过期" | |
color = "green" | |
return format_html('<span style="color:{};">{}</span>',color,ret,) | |
else: | |
ret = "已过期" | |
color = "red" | |
return format_html('<span style="color:{};">{}</span>', color, ret,) | |
Status.short_description = "是否过期" |
添加进度条展示 琢磨了一下,把进度条也堆上了。呵呵
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
class MyAdmin(admin.ModelAdmin): | |
list_display = ("id","Count","Speed") | |
# name: models.py | |
from django.db import models | |
from django.utils.html import format_html | |
class HostDB(models.Model): | |
id = models.AutoField(primary_key=True) | |
Count = models.IntegerField() | |
def Speed(self): | |
return format_html('<progress max="100" value="{}"></progress>',self.Count) | |
Speed.short_description = "当前进度" |
实现查看标签 添加一个查看标签
def Check(self): | |
return format_html('<a href="/admin/MyWeb/hostdb/{}/change/">查看</a>',self.id) |
增加自定义actions: 自定义Action标签,Action标签就是Admin页面中左上角的横线部分,我们自己增加新的.
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
# 必须继承ModelAdmin基类,才可以调整参数,HostDB则是你的表的名称 | |
class MyAdmin(admin.ModelAdmin): | |
admin.site.site_title="自动化后台管理" | |
admin.site.site_header = "Django 管理平台" | |
<省略部分...> | |
def func(self,request,queryset): | |
# 此处可以写一些执行动作 | |
print(self,request,queryset) | |
func.short_description = "自定义active动作" | |
actions = [func,] | |
# Action选项都是在页面上方显示 | |
actions_on_top = True | |
# Action选项都是在页面下方显示 | |
actions_on_bottom = False | |
# 是否显示选择个数 | |
actions_selection_counter = True |
添加防火墙管理模块
{% extends "admin/base_site.html" %} | |
{% load i18n static %} | |
{% block content %} | |
<link rel="stylesheet" href="https://www.blib.cn/cdn/bootstrap3.css" /> | |
<script src="https://www.blib.cn/cdn/jquery.js"></script> | |
<style> | |
#content { | |
padding: 10px 10px; | |
} | |
.panel-body { | |
padding: 10px; | |
} | |
</style> | |
<div class="panel panel-default"> | |
<div class="panel-heading"> | |
<h3 class="panel-title">防火墙配置模块</h3> | |
</div> | |
<div class="panel-body"> | |
<div class="panel panel-default"> | |
<div class="panel-body"> | |
<div class="firewall-port-box"> | |
<input type="text" class="bt-input-text mr5" style="width: 200px;" id="SourceAddr" placeholder="源地址"> | |
<input type="text" class="bt-input-text mr5" id="Remarks" placeholder="备注/说明"> | |
<select id="firewalldType" class="bt-input-text c5 mr5" name="type" style="width:80px;"> | |
<option value="accept">放行IP</option> | |
<option value="drop">屏蔽IP</option> | |
</select> | |
<button id="toAccept" class="btn btn-default btn-sm" type="button">提交更改</button> | |
</div> | |
</div> | |
</div> | |
<div class="panel panel-default"> | |
<div class="panel-body"> | |
<table class="table table-hover"> | |
<thead> | |
<tr> | |
<th>编号</th> | |
<th>IP地址</th> | |
<th>动作</th> | |
<th>添加时间</th> | |
<th>备注</th> | |
<th>操作</th> | |
</tr> | |
</thead> | |
<tbody> | |
{% for item in data %} | |
<tr> | |
<td> {{ item.id }}</td> | |
<td> {{ item.SourceAddr }}</td> | |
<td> {{ item.Action }}</td> | |
<td> {{ item.DataTime }}</td> | |
<td> {{ item.Remarks }}</td> | |
<td><a href="index.html">删除</a></td> | |
</tr> | |
{% endfor %} | |
</tbody> | |
</table> | |
</div> | |
</div> | |
</div> | |
</div> | |
<script> | |
$(document).ready(function(){ | |
$("#toAccept").click(function(){ | |
var message = {"type":null,"SourceAddr":null,"Remarks":null}; | |
message['type'] = $("#firewalldType option:selected").val(); | |
message['SourceAddr'] = $("#SourceAddr").val(); | |
message['Remarks'] = $("#Remarks").val(); | |
data = JSON.stringify(message); | |
$.ajax({ | |
url:"/echo/", | |
type:"POST", | |
dataType:"json", | |
data:data, | |
success:function () { | |
window.location.reload(); | |
} | |
}); | |
}); | |
}); | |
</script> | |
{% endblock %} | |
from django.shortcuts import render,HttpResponse | |
from MyWeb import models | |
import paramiko,time,json | |
ssh = paramiko.SSHClient() | |
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) | |
def ssh_shell(address,username,password,port,command): | |
try: | |
ssh.connect(address,port=port,username=username,password=password,timeout=1) | |
stdin, stdout, stderr = ssh.exec_command(command) | |
result = stdout.read() | |
if not result: | |
result=stderr.read() | |
ssh.close() | |
return result.decode() | |
except Exception: | |
return 0 | |
def echo(request): | |
if request.method == "GET": | |
obj = models.FireWallDB.objects.all() | |
print(obj) | |
return render(request,"index.html",{"data":obj}) | |
else: | |
recv = json.loads(request.body.decode("utf-8")) | |
addr = recv.get("SourceAddr") | |
remak = recv.get("Remarks") | |
if recv.get("type") == "accept": | |
cmd = 'firewall-cmd --add-rich-rule \'rule family=ipv4 source address="{}" accept\''.format(addr) | |
count = models.FireWallDB.objects.filter(SourceAddr=addr).count() | |
if count <2: | |
retn = ssh_shell("192.168.1.20","root","123","22",cmd) | |
if retn !=0: | |
obj = models.FireWallDB() | |
obj.SourceAddr = addr | |
obj.Action = "放行" | |
obj.DataTime = str(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))) | |
obj.Remarks = remak | |
obj.SourceCMD = cmd | |
obj.save() | |
print("ok") | |
elif recv.get("type") == "drop": | |
cmd = 'firewall-cmd --add-rich-rule \'rule family=ipv4 source address="{}" drop\''.format(addr) | |
print(cmd) | |
else: | |
print("最多两个") | |
return HttpResponse("ok") | |
return render(request,"index.html") | |
from django.db import models | |
class FireWallDB(models.Model): | |
id = models.AutoField(primary_key=True) | |
SourceAddr = models.CharField(max_length=64) | |
Action = models.CharField(max_length=64) | |
DataTime = models.CharField(max_length=64) | |
Remarks = models.CharField(max_length=64) | |
SourceCMD = models.CharField(max_length=512) |
简单的Admin定制: 简单的过滤器使用技巧.
# name: settings.py | |
LANGUAGE_CODE = 'zh-hans' | |
TIME_ZONE = 'Asia/Shanghai' | |
# name: apps.py | |
from django.apps import AppConfig | |
class MywebConfig(AppConfig): | |
name = 'MyWeb' | |
verbose_name = "服务器集群" | |
# name: 最后别忘了建库建表 | |
python manage.py makemigrations | |
python manage.py migrate | |
python manage.py createsuperuser | |
# name: models.py | |
from django.db import models | |
from django.utils.html import format_html | |
STATUS_CHOICES = (('d', '正常'),('p', '警告'),('w', '损坏'),) | |
class HostInfo(models.Model): | |
id = models.AutoField(primary_key=True) | |
HostName = models.CharField(max_length=64,verbose_name="主机名") | |
HostAddr = models.CharField(max_length=64,verbose_name="主机IP") | |
DataTime = models.DateField(max_length=64,verbose_name="统计时间") | |
HostStats = models.CharField(max_length=1,choices=STATUS_CHOICES,verbose_name="状态") | |
def __str__(self): | |
return self.HostName | |
# 用于给本表指定别名,这样前端就不是英文的了 | |
class Meta(): | |
verbose_name = "Web前台集群" | |
verbose_name_plural= "Web前台集群" | |
# 自定义方法,主要负责给主机标注颜色 | |
def Status(self): | |
if self.HostStats == 'd': | |
format_td = format_html('<span style="padding:2px;background-color:green;color:white">正常</span>') | |
elif self.HostStats == 'p': | |
format_td = format_html('<span style="padding:2px;background-color:yellow;color:black">警告</span>') | |
elif self.HostStats == 'w': | |
format_td = format_html('<span style="padding:2px;background-color:red;color:white">损坏</span>') | |
return format_td | |
Status.short_description = "状态" | |
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
# 必须继承ModelAdmin基类,才可以调整参数,HostDB则是你的表的名称 | |
class MyAdmin(admin.ModelAdmin): | |
admin.site.site_title="自动化后台管理" | |
admin.site.site_header = "Django 管理平台" | |
# list_display = 你需要或者想要展示在页面中的字段 | |
list_display = ("HostName","HostAddr","DataTime","Status") | |
# search_fields = 添加搜索功能,并以HostName,HostAddr作为搜索条件 | |
search_fields = ("HostName","HostAddr",) | |
# ordering = 设置以id号作为排序条件 | |
ordering = ("id",) | |
# list_per_page = 设置每页显示数据条数 | |
list_per_page = 10 | |
# list_filter = 设置一个过滤器,此处是以hostname作为过滤条件 | |
list_filter = ("HostName",) | |
#list_editable = 设置默认可编辑字段 | |
list_editable = ("DataTime",) | |
# date_hierarchy = 显示详细时间分层筛选 | |
date_hierarchy = 'DataTime' | |
# readonly_fields = 可以设置只读字段,就是无法修改的字段 | |
readonly_fields = ("HostAddr",) | |
# list_display_links 指定点击HostAddr进入编辑状态 | |
list_display_links = ("HostAddr",) |
添加已过期标志: 通过取出当前时间与数据库中现有时间对比,来实现是否过期.
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
class MyAdmin(admin.ModelAdmin): | |
list_display = ("id","date","Status") | |
# name: models.py | |
from django.db import models | |
from django.utils.html import format_html | |
import datetime | |
class HostDB(models.Model): | |
id = models.AutoField(primary_key=True) | |
date = models.CharField(max_length=64) | |
def Status(self): | |
NowData = datetime.date.today() | |
if self.date >= str(NowData): | |
ret = "未过期" | |
color = "green" | |
return format_html('<span style="color:{};">{}</span>',color,ret,) | |
else: | |
ret = "已过期" | |
color = "red" | |
return format_html('<span style="color:{};">{}</span>', color, ret,) | |
Status.short_description = "是否过期" |
添加进度条展示: HTML5默认支持进度条标签,使用progress
我们直接使用这个标签就好了.
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
class MyAdmin(admin.ModelAdmin): | |
list_display = ("id","Count","Speed") | |
# name: models.py | |
from django.db import models | |
from django.utils.html import format_html | |
class HostDB(models.Model): | |
id = models.AutoField(primary_key=True) | |
Count = models.IntegerField() | |
def Speed(self): | |
return format_html('<progress max="100" value="{}"></progress>',self.Count) | |
Speed.short_description = "当前进度" |
增加自定义actions: 自定义Action标签,Action标签就是Admin页面中左上角的横线部分,我们自己增加新的.
# name: admin.py | |
from django.contrib import admin | |
from MyWeb.models import * | |
# 必须继承ModelAdmin基类,才可以调整参数,HostDB则是你的表的名称 | |
class MyAdmin(admin.ModelAdmin): | |
admin.site.site_title="自动化后台管理" | |
admin.site.site_header = "Django 管理平台" | |
<省略部分...> | |
def func(self,request,queryset): | |
# 此处可以写一些执行动作 | |
print(self,request,queryset) | |
func.short_description = "自定义active动作" | |
actions = [func,] | |
# Action选项都是在页面上方显示 | |
actions_on_top = True | |
# Action选项都是在页面下方显示 | |
actions_on_bottom = False | |
# 是否显示选择个数 | |
actions_selection_counter = True |