deviceinfo

This commit is contained in:
RobbieHan
2019-01-31 00:57:11 +08:00
parent ad74ed1802
commit 6765fa8b66
7 changed files with 677 additions and 10 deletions

View File

@@ -4,7 +4,7 @@
from django import forms from django import forms
from .models import Code from .models import Code, DeviceInfo
class CodeCreateForm(forms.ModelForm): class CodeCreateForm(forms.ModelForm):
@@ -43,4 +43,33 @@ class CodeUpdateForm(CodeCreateForm):
raise forms.ValidationError(msg) raise forms.ValidationError(msg)
if matching_code.filter(value=value).exists(): if matching_code.filter(value=value).exists():
msg = 'value{} 已经存在'.format(value) msg = 'value{} 已经存在'.format(value)
raise forms.ValidationError(msg) raise forms.ValidationError(msg)
class DeviceCreateForm(forms.ModelForm):
class Meta:
model = DeviceInfo
exclude = ['dev_connection']
error_messages = {
'hostname': {'required': '请填写设备地址'},
'buyDate': {'required': '请填写购买日期'},
'warrantyDate': {'required': '请填写到保日期'}
}
def clean(self):
cleaned_data = super(DeviceCreateForm, self).clean()
hostname = cleaned_data.get('hostname')
if DeviceInfo.objects.filter(hostname=hostname).count():
raise forms.ValidationError('设备地址:{}已存在'.format(hostname))
class DeviceUpdateForm(DeviceCreateForm):
def clean(self):
cleaned_data = self.cleaned_data
hostname = cleaned_data.get('hostname')
if self.instance:
matching_device = DeviceInfo.objects.exclude(pk=self.instance.pk)
if matching_device.filter(hostname=hostname).exists():
raise forms.ValidationError('设备地址:{}已存在'.format(hostname))

View File

@@ -53,11 +53,11 @@ class ConnectionAbstract(models.Model):
class DeviceAbstract(models.Model): class DeviceAbstract(models.Model):
sys_hostname = models.CharField(max_length=50, blank=True, default='', verbose_name='主机名') sys_hostname = models.CharField(max_length=150, blank=True, default='', verbose_name='主机名')
mac_address = models.CharField(max_length=50, blank=True, default='', verbose_name='MAC地址') mac_address = models.CharField(max_length=150, blank=True, default='', verbose_name='MAC地址')
sn_number = models.CharField(max_length=50, blank=True, default='', verbose_name='SN号码') sn_number = models.CharField(max_length=150, blank=True, default='', verbose_name='SN号码')
os_type = models.CharField(max_length=50, blank=True, default='', verbose_name='系统类型') os_type = models.CharField(max_length=150, blank=True, default='', verbose_name='系统类型')
device_type = models.CharField(max_length=50, blank=True, default='', verbose_name='设备类型') device_type = models.CharField(max_length=150, blank=True, default='', verbose_name='设备类型')
class Meta: class Meta:
abstract = True abstract = True
@@ -100,7 +100,7 @@ class DeviceInfo(AbstractMode, DeviceAbstract, TimeAbstract):
warrantyDate = models.DateField(default=datetime.now, verbose_name="到保日期") warrantyDate = models.DateField(default=datetime.now, verbose_name="到保日期")
desc = models.TextField(blank=True, default='', verbose_name='备注信息') desc = models.TextField(blank=True, default='', verbose_name='备注信息')
changed_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL) changed_by = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL)
history = HistoricalRecords(excluded_fields=['add_time', 'modify_time']) history = HistoricalRecords(excluded_fields=['add_time', 'modify_time', 'parent'])
class Meta: class Meta:
verbose_name = '设备信息' verbose_name = '设备信息'

View File

@@ -27,4 +27,10 @@ urlpatterns = [
path('eam/cabinet/list/', views_eam.CabinetListView.as_view(), name='eam-cabinet-list'), path('eam/cabinet/list/', views_eam.CabinetListView.as_view(), name='eam-cabinet-list'),
path('eam/cabinet/delete/', views_eam.CabinetDeleteView.as_view(), name='eam-cabinet-delete'), path('eam/cabinet/delete/', views_eam.CabinetDeleteView.as_view(), name='eam-cabinet-delete'),
path('eam/device/', views_eam.DeviceView.as_view(), name='eam-device'),
path('eam/device/create/', views_eam.DeviceCreateView.as_view(), name='eam-device-create'),
path('eam/device/update/', views_eam.DeviceUpdateView.as_view(), name='eam-device-update'),
path('eam/device/list/', views_eam.DeviceListView.as_view(), name='eam-device-list'),
path('eam/device/delete/', views_eam.DeviceDeleteView.as_view(), name='eam-device-delete'),
] ]

View File

@@ -1,9 +1,14 @@
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404
from system.mixin import LoginRequiredMixin from system.mixin import LoginRequiredMixin
from custom import (BreadcrumbMixin, SandboxDeleteView, from custom import (BreadcrumbMixin, SandboxDeleteView,
SandboxListView, SandboxUpdateView, SandboxCreateView) SandboxListView, SandboxUpdateView, SandboxCreateView)
from .models import Cabinet from .models import Cabinet, DeviceInfo, Code
from .forms import DeviceCreateForm, DeviceUpdateForm
User = get_user_model()
class CabinetView(LoginRequiredMixin, BreadcrumbMixin, TemplateView): class CabinetView(LoginRequiredMixin, BreadcrumbMixin, TemplateView):
@@ -36,3 +41,80 @@ class CabinetListView(SandboxListView):
class CabinetDeleteView(SandboxDeleteView): class CabinetDeleteView(SandboxDeleteView):
model = Cabinet model = Cabinet
def get_device_public():
all_code = Code.objects.all()
all_cabinet = Cabinet.objects.all()
all_user = User.objects.all()
all_device = DeviceInfo.objects.all()
ret = {
'all_code': all_code,
'all_cabinet': all_cabinet,
'all_user': all_user,
'all_device': all_device,
}
return ret
class DeviceView(LoginRequiredMixin, BreadcrumbMixin, TemplateView):
template_name = 'cmdb/deviceinfo.html'
def get_context_data(self, **kwargs):
device_public = get_device_public()
kwargs.update(device_public)
return super().get_context_data(**kwargs)
class DeviceListView(SandboxListView):
model = DeviceInfo
fields = ['id', 'sys_hostname', 'sn_number', 'os_type', 'device_type', 'hostname', 'mac_address', 'leader']
def get_filters(self):
data = self.request.GET
filters = {}
if 'sys_hostname' in data and data['sys_hostname']:
filters['sys_hostname__icontains'] = data['sys_hostname']
if 'hostname' in data and data['hostname']:
filters['hostname__icontains'] = data['hostname']
if 'network_type' in data and data['network_type']:
filters['network_type'] = data['network_type']
if 'service_type' in data and data['service_type']:
filters['service_type'] = data['service_type']
if 'operation_type' in data and data['operation_type']:
filters['operation_type'] = data['operation_type']
return filters
def get_datatables_paginator(self, request):
context_data = super().get_datatables_paginator(request)
data = context_data['data']
for device in data:
user_id = device['leader']
device['leader'] = get_object_or_404(
User, pk=int(user_id)).name if user_id else ''
return context_data
class DeviceCreateView(SandboxCreateView):
model = DeviceInfo
form_class = DeviceCreateForm
def get_context_data(self, **kwargs):
public_data = get_device_public()
kwargs.update(public_data)
print(public_data)
return super().get_context_data(**kwargs)
class DeviceUpdateView(SandboxUpdateView):
model = DeviceInfo
form_class = DeviceUpdateForm
def get_context_data(self, **kwargs):
public_data = get_device_public()
kwargs.update(public_data)
return super().get_context_data(**kwargs)
class DeviceDeleteView(SandboxDeleteView):
model = DeviceInfo

View File

@@ -1,4 +1,4 @@
django==2.1.2 django==2.1.5
pillow==5.3.0 pillow==5.3.0
mysqlclient==1.3.13 mysqlclient==1.3.13
ipython==7.1.1 ipython==7.1.1

View File

@@ -0,0 +1,329 @@
{% extends "base-left.html" %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{% static 'plugins/datatables/jquery.dataTables.min.css' %}">
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
<link rel="stylesheet" href="{% static 'plugins/select2/select2.min.css' %}">
{% endblock %}
{% block content %}
<!-- Main content -->
<section class="content">
<div id="devlist">
<div class="box box-primary" id="liebiao">
<div class="box-header">
<div class="btn-group pull-left">
<button type="button" id="btnRefresh" class="btn btn-default">
<i class="glyphicon glyphicon-repeat"></i>刷新
</button>
</div>
<div class="btn-group pull-left">&nbsp</div>
<div class="btn-group pull-left">
<button type="button" id="btnCreate" class="btn btn-default">
<i class="glyphicon glyphicon-plus"></i>新增
</button>
</div>
<div class="btn-group pull-left">&nbsp</div>
<div class="btn-group pull-left">
<button type="button" id="btnDelete" class="btn btn-default">
<i class="glyphicon glyphicon-trash"></i>删除
</button>
</div>
</div>
<div class="box-header">
<form class="form-inline" id="queryForm">
<div class="form-group searchArea margin-r-5 margin-top-5">
<label>主机名</label>
<input type="text" name="sys_hostname" class="form-control inputText" id="sys_hostname">
</div>
<div class="form-group searchArea margin-r-5 margin-top-5">
<label>设备地址</label>
<input type="text" name="hostname" class="form-control inputText" id="hostname">
</div>
<div class="form-group searchArea margin-r-5 margin-top-5">
<label>网络类型</label>
<select class="form-control inputText select2" name="network_type" id="network_type">
<option></option>
{% for code in all_code %}
{% ifequal code.parent.key 'NETWORK_TYPE' %}
<option value="{{ code.id }}">{{ code.value }}</option>
{% endifequal %}
{% endfor %}
</select>
</div>
<div class="form-group searchArea margin-r-5 margin-top-5">
<label>服务类型</label>
<select class="form-control inputText select2" name="service_type" , id="service_type">
<option></option>
{% for code in all_code %}
{% if code.parent.key == 'SERVICE_TYPE' %}
<option value="{{ code.id }}">{{ code.value }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<div class="form-group searchArea margin-r-5 margin-top-5">
<label>业务类型</label>
<select class="form-control inputText select2" name="operation_type" , id="operation_type">
<option></option>
{% for code in all_code %}
{% if code.parent.key == 'OPERATION_TYPE' %}
<option value="{{ code.id }}">{{ code.value }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<button type="button" id="btnSearch" class="btn btn-default">
<i class="glyphicon glyphicon-search"></i>查询
</button>
</form>
</div>
<div class="box-body">
<table id="dtbList" class="display" cellspacing="0" width="100%">
<thead>
<tr valign="middle">
<th><input type="checkbox" id="checkAll"></th>
<th>ID</th>
<th>主机名</th>
<th>SN编号</th>
<th>系统类型</th>
<th>设备类型</th>
<th>设备地址</th>
<th>MAC地址</th>
<th>责任人</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<br> <br>
</div>
</div>
</div>
</section>
<!-- /.content -->
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/datatables/jquery.dataTables.min.js' %}"></script>
<script src="{% static 'plugins/datatables/dataTables.const-1.js' %}"></script>
<script src="{% static 'js/plugins/layer/layer.js' %}"></script>
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
<script type="text/javascript">
// 菜单选中高亮
$(function () {
$('#CMDB-EAM').addClass('active');
$('#CMDB-EAM-DEVICE').addClass('active');
});
// datatables 初始化配置
var oDataTable = null;
$(function () {
oDataTable = initTable();
function initTable() {
var oTable = $('#dtbList').DataTable($.extend(true, {},
DATATABLES_CONSTANT.DATA_TABLES.SERVER_SIDE_OPTION,
{
ajax: {
"url": "{% url 'cmdb:eam-device-list' %}",
"data": function (d) {
d.sys_hostname = $("#sys_hostname").val();
d.hostname = $("#hostname").val();
d.network_type = $("#network_type").val();
d.service_type = $("#service_type").val();
d.operation_type = $("#operation_type").val();
}
},
columns: [
DATATABLES_CONSTANT.DATA_TABLES.COLUMN.CHECKBOX,
{
data: "id",
},
{
data: "sys_hostname",
},
{
data: "sn_number",
},
{
data: "os_type",
},
{
data: "device_type",
},
{
data: "hostname",
},
{
data: "mac_address",
},
{
data: "leader",
},
{
data: "id",
bSortable: "false",
render: function (data, type, row, meta) {
var ret = "<button title='详情' onclick='doDetail("
+ data + ")'><i class='glyphicon glyphicon-list-alt'></i></button>";
ret = ret + "<button title='修改' onclick='doUpdate("
+ data + ")'><i class='glyphicon glyphicon-pencil'></i></button>";
ret = ret + "<button title='认证管理' onclick='doDevice2Connection("
+ data + ")'><i class='glyphicon glyphicon-user'></i></button>";
ret = ret + "<button title='删除' onclick='doDelete("
+ data + ")'><i class='glyphicon glyphicon-trash'></i></button>";
return ret;
}
}],
}));
return oTable;
}
});
// 刷新数据
$("#btnRefresh").click(function () {
window.location.reload();
});
//新建数据
$("#btnCreate").click(function () {
var div=layer.open({
type: 2,
title: '新增',
shadeClose: false,
maxmin: true,
area: ['800px', '400px'],
content: "{% url 'cmdb:eam-device-create' %}",
end: function () {
//关闭时做的事情
oDataTable.ajax.reload();
}
});
layer.full(div )
});
//修改数据
function doUpdate(id) {
var div=layer.open({
type: 2,
title: '编辑',
shadeClose: false,
maxmin: true,
area: ['800px', '400px'],
content: ["{% url 'cmdb:eam-device-update' %}" + '?id=' + id, 'no'],
end: function () {
oDataTable.ajax.reload();
}
});
layer.full(div )
}
//checkbox全选
$("#checkAll").on("click", function () {
if ($(this).prop("checked") === true) {
$("input[name='checkList']").prop("checked", $(this).prop("checked"));
$('#example tbody tr').addClass('selected');
} else {
$("input[name='checkList']").prop("checked", false);
$('#example tbody tr').removeClass('selected');
}
});
//批量删除
$("#btnDelete").click(function () {
if ($("input[name='checkList']:checked").length == 0) {
layer.msg("请选择要删除的记录");
return;
}
var arrId = new Array();
$("input[name='checkList']:checked").each(function () {
//alert($(this).val());
arrId.push($(this).val());
});
sId = arrId.join(',');
layer.alert('确定删除吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'cmdb:eam-device-delete' %}",
data: {"id": sId, csrfmiddlewaretoken: '{{ csrf_token }}'},
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert("操作成功", {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert("操作失败", {icon: 2});
}
return;
}
});
}
});
});
//删除单个数据
function doDelete(id) {
layer.alert('确定删除吗?', {
title: '提示'
, icon: 3 //0:感叹号 1对号 2差号 3问号 4小锁 5哭脸 6笑脸
, time: 0 //不自动关闭
, btn: ['YES', 'NO']
, yes: function (index) {
layer.close(index);
$.ajax({
type: "POST",
url: "{% url 'cmdb:eam-device-delete' %}",
data: {"id": id, csrfmiddlewaretoken: '{{ csrf_token }}'},
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('删除成功', {icon: 1});
oDataTable.ajax.reload();
} else {
//alert(msg.message);
layer.alert('删除失败', {icon: 2});
}
return;
}
});
}
});
}
//select2
$(function () {
//Initialize Select2 Elements
$(".select2").select2();
});
$("#btnSearch").click(function(){
oDataTable.ajax.reload();
});
</script>
{% endblock %}

View File

@@ -0,0 +1,221 @@
{% extends 'base-layer.html' %}
{% load staticfiles %}
{% block css %}
<link rel="stylesheet" href="{%static 'plugins/select2/select2.min.css' %}">
<link rel="stylesheet" href="{% static 'js/plugins/layer/skin/layer.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap-datetimepicker.min.css' %}">
{% endblock %}
{% block main %}
<div class="box box-danger">
<form class="form-horizontal" id="addForm" method="post">
<input type="hidden" name='id' value="{{ deviceinfo.id }}" />
<input type="hidden" name='changed_by' value="{{ request.user.id }}" />
{% csrf_token %}
<div class="box-body">
<fieldset>
<legend>
</legend>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">主机名</label>
<div class="col-sm-3">
<input class="form-control" name="sys_hostname" type="text" value="{{ deviceinfo.sys_hostname }}" />
</div>
<label class="col-sm-2 control-label">SN编号</label>
<div class="col-sm-3">
<input class="form-control" name="sn_number" type="text" value="{{ deviceinfo.sn_number }}" />
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">系统类型</label>
<div class="col-sm-3">
<input class="form-control" name="os_type" type="text" value="{{ deviceinfo.os_type }}" />
</div>
<label class="col-sm-2 control-label">设备类型</label>
<div class="col-sm-3">
<input class="form-control" name="device_type" type="text" value="{{ deviceinfo.device_type }}"/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">设备地址</label>
<div class="col-sm-3">
<input class="form-control" name="hostname" type="text" value="{{ deviceinfo.hostname }}" />
</div>
<label class="col-sm-2 control-label">MAC地址</label>
<div class="col-sm-3">
<input class="form-control" name="mac_address" type="text" value="{{ deviceinfo.mac_address }}"/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">网络类型</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="network_type">
<option {% ifequal deviceinfo.network_type '' %}selected="selected"{% endifequal %}></option>
{% for code in all_code %}
{% ifequal code.parent.key 'NETWORK_TYPE' %}
<option value="{{ code.id }}" {% ifequal deviceinfo.network_type code.id %}selected="selected"{% endifequal %}>
{{ code.value }}</option>
{% endifequal %}
{% endfor %}
</select>
</div>
<label class="col-sm-2 control-label">服务类型</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="service_type">
<option {% ifequal deviceinfo.service_type '' %}selected="selected"{% endifequal %}></option>
{% for code in all_code %}
{% if code.parent.key == 'SERVICE_TYPE' %}
<option value="{{ code.id }}" {% ifequal deviceinfo.service_type code.id %}selected="selected"{% endifequal %}>
{{ code.value }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">业务类型</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="operation_type">
<option {% ifequal deviceinfo.operation_type '' %}selected="selected"{% endifequal %}></option>
{% for code in all_code %}
{% if code.parent.key == 'OPERATION_TYPE' %}
<option value="{{ code.id }}" {% ifequal deviceinfo.operation_type code.id %}selected="selected"{% endifequal %}>
{{ code.value }}</option>
{% endif %}
{% endfor %}
</select>
</div>
<label class="col-sm-2 control-label">机柜信息</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="dev_cabinet">
<option {% ifequal deviceinfo.dev_cabinet '' %}selected="selected"{% endifequal %}></option>
{% for cabinet in all_cabinet %}
<option value="{{ cabinet.id }}" {% ifequal deviceinfo.dev_cabinet cabinet.id %}selected="selected"{% endifequal %}>
{{ cabinet.number }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">购买日期</label>
<div class="col-sm-3">
<input type="text" class="form-control pull-right form_datetime" name="buyDate"
value="{{ deviceinfo.buyDate | date:'Y-m-d' }}" readonly/>
</div>
<label class="col-sm-2 control-label">质保日期</label>
<div class="col-sm-3">
<input type="text" class="form-control pull-right form_datetime" name="warrantyDate"
value="{{ deviceinfo.warrantyDate | date:'Y-m-d' }}" readonly/>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">所属</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="parent">
<option {% ifequal deviceinfo.parent_id '' %}selected="selected"{% endifequal %}></option>
{% for device in all_device %}
<option value="{{ device.id }}" {% ifequal deviceinfo.parent_id device.id %}selected="selected"{% endifequal %}>
{{ device.sys_hostname }}({{ device.hostname }})</option>
{% endfor %}
</select>
</div>
<label class="col-sm-2 control-label">责任人</label>
<div class="col-sm-3">
<select class="form-control select2" style="width:100%;" name="leader">
<option {% ifequal deviceinfo.leader '' %}selected="selected"{% endifequal %}></option>
{% for u in all_user %}
<option value="{{ u.id }}" {% ifequal deviceinfo.leader u.id %}selected="selected"{% endifequal %}>
{{ u.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-group has-feedback">
<label class="col-sm-2 control-label">备注信息</label>
<div class="col-sm-8">
<textarea class="form-control" name="desc" rows="5" >{{ deviceinfo.desc }}</textarea>
</div>
</div>
</fieldset>
</div>
<div class="box-footer ">
<div class="row span7 text-center ">
<button type="button" id="btnCancel" class="btn btn-default margin-right " >重置</button>
<button type="button" id="btnSave" class="btn btn-info margin-right " >保存</button>
</div>
</div>
</form>
</div>
{% endblock %}
{% block javascripts %}
<script src="{% static 'plugins/select2/select2.full.min.js' %}"></script>
<script src="{% static 'bootstrap/js/bootstrap-datetimepicker.js' %}"></script>
<script type="text/javascript">
function getUrl() {
if ($("input[name='id']").val()) {
var url = "{% url 'cmdb:eam-device-update' %}";
} else {
var url = "{% url 'cmdb:eam-device-create' %}";
}
return url
}
$("#btnSave").click(function () {
var data = $("#addForm").serialize();
$.ajax({
type: $("#addForm").attr('method'),
url: getUrl(),
data: data,
cache: false,
success: function (msg) {
if (msg.result) {
layer.alert('数据保存成功!', {icon: 1}, function (index) {
parent.layer.closeAll(); //关闭所有弹窗
});
} else {
layer.alert(msg.error, {icon: 5});
//$('errorMessage').html(msg.message)
}
return;
}
});
});
/*点取消刷新新页面*/
$("#btnCancel").click(function () {
window.location.reload();
})
/*input 时间输入选择*/
$(".form_datetime").datetimepicker({
language: 'zh',
minView: 'month', //选择范围知道日期不选择时分
//weekStart: 1,
//todayBtn: 1,
autoclose: 1,
todayHighlight: 1,
//startView: 2,
forceParse: 0,
showMeridian: 1,
format: 'yyyy-mm-dd'
}).on('changeDate', function (ev) {
$(this).datetimepicker('hide');
});
// select2
$(function () {
//Initialize Select2 Elements
$(".select2").select2();
});
</script>
{% endblock %}