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 .models import Code
from .models import Code, DeviceInfo
class CodeCreateForm(forms.ModelForm):
@@ -43,4 +43,33 @@ class CodeUpdateForm(CodeCreateForm):
raise forms.ValidationError(msg)
if matching_code.filter(value=value).exists():
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):
sys_hostname = models.CharField(max_length=50, blank=True, default='', verbose_name='主机名')
mac_address = models.CharField(max_length=50, blank=True, default='', verbose_name='MAC地址')
sn_number = models.CharField(max_length=50, blank=True, default='', verbose_name='SN号码')
os_type = models.CharField(max_length=50, blank=True, default='', verbose_name='系统类型')
device_type = 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=150, blank=True, default='', verbose_name='MAC地址')
sn_number = models.CharField(max_length=150, blank=True, default='', verbose_name='SN号码')
os_type = models.CharField(max_length=150, blank=True, default='', verbose_name='系统类型')
device_type = models.CharField(max_length=150, blank=True, default='', verbose_name='设备类型')
class Meta:
abstract = True
@@ -100,7 +100,7 @@ class DeviceInfo(AbstractMode, DeviceAbstract, TimeAbstract):
warrantyDate = models.DateField(default=datetime.now, verbose_name="到保日期")
desc = models.TextField(blank=True, default='', verbose_name='备注信息')
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:
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/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.contrib.auth import get_user_model
from django.shortcuts import get_object_or_404
from system.mixin import LoginRequiredMixin
from custom import (BreadcrumbMixin, SandboxDeleteView,
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):
@@ -36,3 +41,80 @@ class CabinetListView(SandboxListView):
class CabinetDeleteView(SandboxDeleteView):
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
mysqlclient==1.3.13
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 %}