mirror of https://github.com/jumpserver/jumpserver
Merge branch 'master' of code.simcu.com:jumpserver/jumpserver
commit
edd60cad11
|
@ -0,0 +1,35 @@
|
||||||
|
# coding:utf-8
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
from .models import IDC, Asset, AssetGroup
|
||||||
|
|
||||||
|
|
||||||
|
class AssetForm(forms.ModelForm):
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = Asset
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
"ip", "other_ip", "hostname", "port", "group", "username", "password", "idc", "mac_addr",
|
||||||
|
"remote_card_ip", "brand", "cpu", "memory", "disk", "os", "cabinet_no", "cabinet_pos",
|
||||||
|
"number", "status", "type", "env", "sn", "is_active", "comment"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class AssetGroupForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = AssetGroup
|
||||||
|
fields = [
|
||||||
|
"name", "comment"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class IdcForm(forms.ModelForm):
|
||||||
|
class Meta:
|
||||||
|
model = IDC
|
||||||
|
fields = ['name', "bandwidth", "operator", 'contact', 'phone', 'address', 'network', 'comment']
|
||||||
|
widgets = {
|
||||||
|
'name': forms.TextInput(attrs={'placeholder': 'Name'}),
|
||||||
|
'network': forms.Textarea(
|
||||||
|
attrs={'placeholder': '192.168.1.0/24\n192.168.2.0/24'})
|
||||||
|
}
|
|
@ -0,0 +1,111 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10 on 2016-08-14 08:12
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Asset',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('ip', models.CharField(blank=True, max_length=32, verbose_name='\u4e3b\u673aIP')),
|
||||||
|
('other_ip', models.CharField(blank=True, max_length=255, null=True, verbose_name='\u5176\u4ed6IP')),
|
||||||
|
('remote_card_ip', models.CharField(blank=True, max_length=16, null=True, verbose_name='\u8fdc\u63a7\u5361IP')),
|
||||||
|
('hostname', models.CharField(max_length=128, unique=True, verbose_name='\u4e3b\u673a\u540d')),
|
||||||
|
('port', models.IntegerField(blank=True, null=True, verbose_name='\u7aef\u53e3\u53f7')),
|
||||||
|
('username', models.CharField(blank=True, max_length=16, null=True, verbose_name='\u7ba1\u7406\u7528\u6237\u540d')),
|
||||||
|
('password', models.CharField(blank=True, max_length=256, null=True, verbose_name='\u5bc6\u7801')),
|
||||||
|
('mac_addr', models.CharField(blank=True, max_length=20, null=True, verbose_name='MAC\u5730\u5740')),
|
||||||
|
('brand', models.CharField(blank=True, max_length=64, null=True, verbose_name='\u786c\u4ef6\u5382\u5546\u578b\u53f7')),
|
||||||
|
('cpu', models.CharField(blank=True, max_length=64, null=True, verbose_name='CPU')),
|
||||||
|
('memory', models.CharField(blank=True, max_length=128, null=True, verbose_name='\u5185\u5b58')),
|
||||||
|
('disk', models.CharField(blank=True, max_length=1024, null=True, verbose_name='\u786c\u76d8')),
|
||||||
|
('os', models.CharField(blank=True, max_length=128, null=True, verbose_name='\u7cfb\u7edf\u4fe1\u606f')),
|
||||||
|
('cabinet_no', models.CharField(blank=True, max_length=32, null=True, verbose_name='\u673a\u67dc\u53f7')),
|
||||||
|
('cabinet_pos', models.IntegerField(blank=True, null=True, verbose_name='\u673a\u5668\u4f4d\u7f6e')),
|
||||||
|
('number', models.CharField(blank=True, max_length=32, null=True, verbose_name='\u8d44\u4ea7\u7f16\u53f7')),
|
||||||
|
('sn', models.CharField(blank=True, max_length=128, null=True, verbose_name='SN\u7f16\u53f7')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='\u521b\u5efa\u8005')),
|
||||||
|
('is_active', models.BooleanField(default=True, verbose_name='\u662f\u5426\u6fc0\u6d3b')),
|
||||||
|
('date_added', models.DateTimeField(auto_now=True, null=True)),
|
||||||
|
('comment', models.CharField(blank=True, max_length=128, null=True, verbose_name='\u5907\u6ce8')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'asset',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AssetExtend',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='AssetGroup',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=64, unique=True)),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='\u521b\u5efa\u8005')),
|
||||||
|
('comment', models.CharField(blank=True, max_length=128, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'assetgroup',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='IDC',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=32, verbose_name='\u673a\u623f\u540d\u79f0')),
|
||||||
|
('bandwidth', models.CharField(blank=True, default='', max_length=32, null=True, verbose_name='\u673a\u623f\u5e26\u5bbd')),
|
||||||
|
('contact', models.CharField(blank=True, default='', max_length=16, null=True, verbose_name='\u8054\u7cfb\u4eba')),
|
||||||
|
('phone', models.CharField(blank=True, default='', max_length=32, null=True, verbose_name='\u8054\u7cfb\u7535\u8bdd')),
|
||||||
|
('address', models.CharField(blank=True, default='', max_length=128, null=True, verbose_name='\u673a\u623f\u5730\u5740')),
|
||||||
|
('network', models.TextField(blank=True, default='', null=True, verbose_name='IP\u5730\u5740\u6bb5')),
|
||||||
|
('date_added', models.DateField(auto_now=True, null=True)),
|
||||||
|
('operator', models.CharField(blank=True, default='', max_length=32, null=True, verbose_name='\u8fd0\u8425\u5546')),
|
||||||
|
('created_by', models.CharField(blank=True, max_length=32, null=True, verbose_name='\u521b\u5efa\u8005')),
|
||||||
|
('comment', models.CharField(blank=True, default='', max_length=128, null=True, verbose_name='\u5907\u6ce8')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'idc',
|
||||||
|
'verbose_name': 'IDC\u673a\u623f',
|
||||||
|
'verbose_name_plural': 'IDC\u673a\u623f',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='env',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='asset_env_extend', to='assets.AssetExtend', verbose_name='\u6240\u5c5e\u4e3b\u673a\u7ec4\u73af\u5883'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='group',
|
||||||
|
field=models.ManyToManyField(blank=True, to='assets.AssetGroup', verbose_name='\u6240\u5c5e\u4e3b\u673a\u7ec4'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='idc',
|
||||||
|
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='assets.IDC', verbose_name='\u673a\u623f'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='status',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='asset_status_extend', to='assets.AssetExtend', verbose_name='\u673a\u5668\u72b6\u6001'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='asset',
|
||||||
|
name='type',
|
||||||
|
field=models.ManyToManyField(blank=True, related_name='asset_type_extend', to='assets.AssetExtend', verbose_name='\u673a\u5668\u7c7b\u578b'),
|
||||||
|
),
|
||||||
|
]
|
|
@ -1,5 +1,87 @@
|
||||||
|
# coding:utf-8
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
# Create your models here.
|
|
||||||
|
class AssetGroup(models.Model):
|
||||||
|
name = models.CharField(max_length=64, unique=True)
|
||||||
|
created_by = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"创建者")
|
||||||
|
comment = models.CharField(max_length=128, blank=True, null=True)
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'assetgroup'
|
||||||
|
|
||||||
|
|
||||||
|
class IDC(models.Model):
|
||||||
|
name = models.CharField(max_length=32, verbose_name=u'机房名称')
|
||||||
|
bandwidth = models.CharField(max_length=32, blank=True, null=True, default='', verbose_name=u'机房带宽')
|
||||||
|
contact = models.CharField(max_length=16, blank=True, null=True, default='', verbose_name=u'联系人')
|
||||||
|
phone = models.CharField(max_length=32, blank=True, null=True, default='', verbose_name=u'联系电话')
|
||||||
|
address = models.CharField(max_length=128, blank=True, null=True, default='', verbose_name=u"机房地址")
|
||||||
|
network = models.TextField(blank=True, null=True, default='', verbose_name=u"IP地址段")
|
||||||
|
date_added = models.DateField(auto_now=True, null=True)
|
||||||
|
operator = models.CharField(max_length=32, blank=True, default='', null=True, verbose_name=u"运营商")
|
||||||
|
created_by = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"创建者")
|
||||||
|
comment = models.CharField(max_length=128, blank=True, default='', null=True, verbose_name=u"备注")
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'idc'
|
||||||
|
verbose_name = u"IDC机房"
|
||||||
|
verbose_name_plural = verbose_name
|
||||||
|
|
||||||
|
|
||||||
|
class AssetExtend(models.Model):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Asset(models.Model):
|
||||||
|
ip = models.CharField(max_length=32, blank=True, verbose_name="主机IP")
|
||||||
|
other_ip = models.CharField(max_length=255, blank=True, null=True, verbose_name="其他IP")
|
||||||
|
remote_card_ip = models.CharField(max_length=16, blank=True, null=True, verbose_name=u'远控卡IP')
|
||||||
|
hostname = models.CharField(unique=True, max_length=128, verbose_name=u"主机名")
|
||||||
|
port = models.IntegerField(blank=True, null=True, verbose_name=u"端口号")
|
||||||
|
group = models.ManyToManyField(AssetGroup, blank=True, verbose_name=u"所属主机组")
|
||||||
|
username = models.CharField(max_length=16, blank=True, null=True, verbose_name=u"管理用户名")
|
||||||
|
password = models.CharField(max_length=256, blank=True, null=True, verbose_name=u"密码")
|
||||||
|
idc = models.ForeignKey(IDC, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=u'机房')
|
||||||
|
mac_addr = models.CharField(max_length=20, blank=True, null=True, verbose_name=u"MAC地址")
|
||||||
|
brand = models.CharField(max_length=64, blank=True, null=True, verbose_name=u'硬件厂商型号')
|
||||||
|
cpu = models.CharField(max_length=64, blank=True, null=True, verbose_name=u'CPU')
|
||||||
|
memory = models.CharField(max_length=128, blank=True, null=True, verbose_name=u'内存')
|
||||||
|
disk = models.CharField(max_length=1024, blank=True, null=True, verbose_name=u'硬盘')
|
||||||
|
os = models.CharField(max_length=128, blank=True, null=True, verbose_name=u'系统信息')
|
||||||
|
cabinet_no = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'机柜号')
|
||||||
|
cabinet_pos = models.IntegerField(blank=True, null=True, verbose_name=u'机器位置')
|
||||||
|
number = models.CharField(max_length=32, blank=True, null=True, verbose_name=u'资产编号')
|
||||||
|
status = models.ManyToManyField(AssetExtend, blank=True, related_name="asset_status_extend", verbose_name="机器状态")
|
||||||
|
type = models.ManyToManyField(AssetExtend, blank=True, related_name="asset_type_extend", verbose_name="机器类型")
|
||||||
|
env = models.ManyToManyField(AssetExtend, blank=True, related_name="asset_env_extend", verbose_name="所属主机组环境")
|
||||||
|
sn = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"SN编号")
|
||||||
|
created_by = models.CharField(max_length=32, blank=True, null=True, verbose_name=u"创建者")
|
||||||
|
is_active = models.BooleanField(default=True, verbose_name=u"是否激活")
|
||||||
|
date_added = models.DateTimeField(auto_now=True, null=True)
|
||||||
|
comment = models.CharField(max_length=128, blank=True, null=True, verbose_name=u"备注")
|
||||||
|
|
||||||
|
def __unicode__(self):
|
||||||
|
return self.ip
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'asset'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,197 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% load bootstrap %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<div class="ibox float-e-margins">
|
||||||
|
<div id="ibox-content" class="ibox-title">
|
||||||
|
<h5> 填写资产基本信息 </h5>
|
||||||
|
<div class="ibox-tools">
|
||||||
|
<a class="collapse-link">
|
||||||
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
|
<i class="fa fa-wrench"></i>
|
||||||
|
</a>
|
||||||
|
<a class="close-link">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ibox-content">
|
||||||
|
<div class="panel blank-panel">
|
||||||
|
<div class="panel-options">
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li class="active"><a href="{% url 'assets:asset-add' %}" class="text-center"><i class="fa fa-laptop"></i> 单台添加 </a></li>
|
||||||
|
{# <li><a href="{% url 'asset_add_batch' %}" class="text-center"><i class="fa fa-bar-chart-o"></i> 批量添加 </a></li>#}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div id="tab-1" class="ibox float-e-margins tab-pane active">
|
||||||
|
{% if error %}
|
||||||
|
<div class="alert alert-warning text-center">{{ error }}</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if msg %}
|
||||||
|
<div class="alert alert-success text-center">{{ msg }}</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form id="assetForm" method="post" class="form-horizontal">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
{{ form.hostname|bootstrap_horizontal }}
|
||||||
|
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
{{ form.ip|bootstrap_horizontal }}
|
||||||
|
<p class="col-sm-offset-2">Tips: 如果IP地址不填写, IP默认会设置与主机名一致</p>
|
||||||
|
|
||||||
|
{# <div class="hr-line-dashed"></div>#}
|
||||||
|
{# <div class="form-group">#}
|
||||||
|
{# <label for="j_group" class="col-sm-2 control-label">管理用户<span class="red-fonts"> *</span></label>#}
|
||||||
|
{# <div class="col-sm-2">#}
|
||||||
|
{# <div class="radio i-checks">#}
|
||||||
|
{# <label style="padding-left: 0">#}
|
||||||
|
{# <input type="checkbox" checked="checked" id="id_use_default_auth" name="use_default_auth"><span> 使用默认 </span>#}
|
||||||
|
{# </label>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
{# <p class="col-sm-offset-2">Tips: 管理用户是服务器存在的root或拥有sudo的用户,用来推送系统用户</p>#}
|
||||||
|
{# <div class="form-group" id="admin_account" style="display: none">#}
|
||||||
|
{# <label class="col-sm-2 control-label"> <span class="red-fonts"></span> </label>#}
|
||||||
|
{# <div class="col-sm-3">#}
|
||||||
|
{# <input type="text" placeholder="Username" name="username" class="form-control">#}
|
||||||
|
{# </div>#}
|
||||||
|
{##}
|
||||||
|
{# <label class="col-sm-1 control-label"> <span class="red-fonts"></span> </label>#}
|
||||||
|
{# <div class="col-sm-4">#}
|
||||||
|
{# <input type="password" placeholder="Password" name="password" class="form-control">#}
|
||||||
|
{# </div>#}
|
||||||
|
{# </div>#}
|
||||||
|
|
||||||
|
<div class="form-group" id="id_port">
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
<label class="col-sm-2 control-label"> 端口<span class="red-fonts">*</span> </label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<input type="text" placeholder="Port" name="port" class="form-control" value="{{ default_port }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
{{ form.group|bootstrap_horizontal }}
|
||||||
|
|
||||||
|
{# {{ af.is_active|bootstrap_horizontal }}#}
|
||||||
|
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
<div class="form-group"><label class="col-sm-2 control-label"> 是否激活<span class="red-fonts"> *</span> </label>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="radio i-checks">
|
||||||
|
<label> <input type="radio" checked="" value="1" name="is_active">激活 </label>
|
||||||
|
<label> <input type="radio" value="0" name="is_active"> 禁用</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="hr-line-dashed"></div>
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-4 col-sm-offset-2">
|
||||||
|
<button class="btn btn-white" type="reset"> 重置 </button>
|
||||||
|
<button class="btn btn-primary" type="submit"> 提交 </button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block self_footer_js %}
|
||||||
|
<script>
|
||||||
|
$('document').ready(function(){
|
||||||
|
var check_default = "{{ default_setting.name }}";
|
||||||
|
console.log(check_default);
|
||||||
|
if (check_default != 'default'){
|
||||||
|
$('#id_use_default_auth').attr('disabled', true);
|
||||||
|
$('#id_use_default_auth').attr('checked', false);
|
||||||
|
$('#admin_account').css('display', 'block');
|
||||||
|
} else {
|
||||||
|
$('#id_use_default_auth').click(function(){
|
||||||
|
if ($(this).is(':checked')){
|
||||||
|
$('#admin_account').css('display', 'none');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$('#admin_account').css('display', 'block');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
var required_fields = ["id_hostname", "id_port"];
|
||||||
|
required_fields.forEach(function(field) {
|
||||||
|
$('label[for="' + field + '"]').parent().addClass("required");
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#assetForm').validator({
|
||||||
|
timely: 2,
|
||||||
|
theme: "yellow_right_effect",
|
||||||
|
rules: {
|
||||||
|
check_ip: [/^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])(\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])){3}$/, 'ip地址不正确'],
|
||||||
|
check_port: [/^\d{1,5}$/, '端口号不正确'],
|
||||||
|
use_default_auth: function() {
|
||||||
|
var str1 = $("#id_use_default_auth").is(":checked");
|
||||||
|
if (str1 == true){
|
||||||
|
var decide = false;
|
||||||
|
} else {
|
||||||
|
var decide = true;
|
||||||
|
}
|
||||||
|
return decide}
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
"ip": {
|
||||||
|
rule: "check_ip;",
|
||||||
|
tip: "输入IP",
|
||||||
|
ok: "",
|
||||||
|
msg: {required: "必须填写!"}
|
||||||
|
},
|
||||||
|
"hostname": {
|
||||||
|
rule: "required;length[0~53]",
|
||||||
|
tip: "填写主机名",
|
||||||
|
ok: "",
|
||||||
|
msg: {required: "必须填写!"}
|
||||||
|
},
|
||||||
|
"port": {
|
||||||
|
rule: "required",
|
||||||
|
tip: "输入端口号",
|
||||||
|
ok: "",
|
||||||
|
msg: {required: "必须填写!"}
|
||||||
|
},
|
||||||
|
"username": {
|
||||||
|
rule: "required(use_default_auth)",
|
||||||
|
tip: "输入用户名",
|
||||||
|
ok: "",
|
||||||
|
msg: {required: "必须填写!"}
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
rule: "required(use_default_auth);length[0~64]",
|
||||||
|
tip: "输入密码",
|
||||||
|
ok: "",
|
||||||
|
msg: {required: "必须填写!"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
valid: function(form) {
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,430 @@
|
||||||
|
{% extends 'base.html' %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<div class="wrapper wrapper-content animated fadeInRight">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<div class="ibox float-e-margins" id="all">
|
||||||
|
<div class="ibox-title">
|
||||||
|
<h5> 主机详细信息列表</h5>
|
||||||
|
<div class="ibox-tools">
|
||||||
|
<a class="collapse-link">
|
||||||
|
<i class="fa fa-chevron-up"></i>
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||||
|
<i class="fa fa-wrench"></i>
|
||||||
|
</a>
|
||||||
|
<a class="close-link">
|
||||||
|
<i class="fa fa-times"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ibox-content">
|
||||||
|
<form id="asset_form">
|
||||||
|
<div class="col-sm-1" style="padding-left: 0">
|
||||||
|
<a href="{% url 'assets:asset-add' %}" class="btn btn-sm btn-primary "> 添加资产 </a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-7" style="padding-left: 0px">
|
||||||
|
<label>
|
||||||
|
<select name="idc" class="form-control m-b input-sm" onchange="change_info()">
|
||||||
|
<option value="">机房</option>
|
||||||
|
{% for idc in idc_all %}
|
||||||
|
{% ifequal idc.name idc_name %}
|
||||||
|
<option value="{{idc.name}}" selected> {{ idc.name|slice:":20" }}</option>
|
||||||
|
{% else %}
|
||||||
|
<option value="{{idc.name}}"> {{ idc.name|slice:":20" }}</option>
|
||||||
|
{% endifequal %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<select name="group" class="form-control m-b input-sm" onchange="change_info()">
|
||||||
|
<option value="">主机组</option>
|
||||||
|
{% for asset_group in asset_group_all %}
|
||||||
|
{% ifequal asset_group.name group_name %}
|
||||||
|
<option value="{{ asset_group.name }}" selected> {{ asset_group.name|slice:":20" }} </option>
|
||||||
|
{% else %}
|
||||||
|
<option value="{{ asset_group.name }}"> {{ asset_group.name|slice:":20" }} </option>
|
||||||
|
{% endifequal %}
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<select name="asset_type" class="form-control m-b input-sm" onchange="change_info()">
|
||||||
|
<option value="">资产类型</option>
|
||||||
|
{# {% for type in asset_types %}#}
|
||||||
|
{# {% ifequal type.0|int2str asset_type %}#}
|
||||||
|
{# <option value="{{ type.0 }}" selected> {{ type.1 }}</option>#}
|
||||||
|
{# {% else %}#}
|
||||||
|
{# <option value="{{ type.0 }}"> {{ type.1 }}</option>#}
|
||||||
|
{# {% endifequal %}#}
|
||||||
|
{# {% endfor %}#}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label>
|
||||||
|
<select name="status" class="form-control m-b input-sm" onchange="change_info()">
|
||||||
|
<option value="">资产状态</option>
|
||||||
|
{# {% for s in asset_status %}#}
|
||||||
|
{# {% ifequal s.0|int2str status %}#}
|
||||||
|
{# <option value="{{ s.0 }}" selected> {{ s.1 }}</option>#}
|
||||||
|
{# {% else %}#}
|
||||||
|
{# <option value="{{ s.0 }}"> {{ s.1 }}</option>#}
|
||||||
|
{# {% endifequal %}#}
|
||||||
|
{# {% endfor %}#}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-4" style="padding-right: 0">
|
||||||
|
<div class="input-group inline-group">
|
||||||
|
<input type="text" class="form-control m-b input-sm" id="search_input" name="keyword" value="{{ keyword }}" placeholder="Search">
|
||||||
|
<input type="text" style="display: none">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button id='search_btn' href="{% url 'assets:asset-list' %}?search=true" type="button" class="btn btn-sm btn-primary search-btn" onclick="change_info()">
|
||||||
|
- 搜索 -
|
||||||
|
</button>
|
||||||
|
<button type="button" href="{% url 'assets:asset-list' %}?export=true" name="export" class="btn btn-sm btn-success search-btn-excel" onclick="return false">
|
||||||
|
- 导出 -
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="export"></div>
|
||||||
|
<table class="table table-striped table-bordered table-hover " id="editable" name="editable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="text-center">
|
||||||
|
<input id="checkall" type="checkbox" class="i-checks" name="checkall" value="checkall" data-editable='false' onclick="check_all('asset_form')">
|
||||||
|
</th>
|
||||||
|
<th class="text-center"> 主机名 </th>
|
||||||
|
<th class="text-center" name="ip"> IP地址 </th>
|
||||||
|
<th class="text-center"> IDC </th>
|
||||||
|
<th class="text-center"> 所属主机组 </th>
|
||||||
|
{# <th class="text-center"> 配置信息 </th>#}
|
||||||
|
<th class="text-center"> 操作系统 </th>
|
||||||
|
<th class="text-center"> cpu核数 </th>
|
||||||
|
<th class="text-center"> 内存 </th>
|
||||||
|
<th class="text-center"> 硬盘 </th>
|
||||||
|
<th class="text-center"> 操作 </th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for asset in assets %}
|
||||||
|
<tr class="gradeX">
|
||||||
|
<td class="text-center" name="id" value="{{ asset.id }}" data-editable='false'>
|
||||||
|
<input name="id" value="{{ asset.id }}" type="checkbox" class="i-checks">
|
||||||
|
</td>
|
||||||
|
<td class="text-center hostname"> <a href="{% url 'assets:asset-detail' %}?id={{ asset.id }}">{{ asset.hostname|default_if_none:"" }}</a></td>
|
||||||
|
<td class="text-center"> {{ asset.ip|default_if_none:"" }} </td>
|
||||||
|
<td class="text-center"> {{ asset.idc.name|default_if_none:"" }} </td>
|
||||||
|
{# <td class="text-center">{{ asset.group.all|group_str2 }}</td>#}
|
||||||
|
{# <td class="text-center">{{ asset.cpu }}|{{ asset.memory }}|{{ asset.disk }}</td>#}
|
||||||
|
<td class="text-center">{{ asset.system_type|default_if_none:"" }}{{ asset.system_version|default_if_none:"" }}</td>
|
||||||
|
<td class="text-center"> {{ asset.cpu|default_if_none:"" }} </td>
|
||||||
|
<td class="text-center"> {{ asset.memory|default_if_none:"" }}{% if asset.memory %}G{% endif %}</td>
|
||||||
|
<td class="text-center"> {{ asset.disk }}{% if asset.disk %}G{% endif %}</td>
|
||||||
|
<td class="text-center" data-editable='false'>
|
||||||
|
{# <a href="{% url 'asset_edit' %}?id={{ asset.id }}" class="btn btn-xs btn-info">编辑</a>#}
|
||||||
|
<a value="{{ asset.id }}" class="conn btn btn-xs btn-warning">连接</a>
|
||||||
|
{# <a value="{% url 'asset_del' %}?id={{ asset.id }}" class="btn btn-xs btn-danger asset_del">删除</a>#}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<input type="button" id="asset_del" class="btn btn-danger btn-sm" name="del_button" value="删除"/>
|
||||||
|
{# <a value="{% url 'asset_edit_batch' %}" type="button" class="btn btn-sm btn-warning iframe">修改</a>#}
|
||||||
|
<input type="button" id="asset_update" class="btn btn-info btn-sm" name="update_button" value="更新"/>
|
||||||
|
{# <input type="button" id="asset_update_all" class="btn btn-primary btn-sm" name="update_button" value="更新全部"/>#}
|
||||||
|
<input type="button" id="exec_cmd" class="btn btn-sm btn-primary" name="exec_cmd" value="执行命令"/>
|
||||||
|
</div>
|
||||||
|
{# {% include 'paginator.html' %}#}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block self_footer_js %}
|
||||||
|
<script>
|
||||||
|
$(document).ready(function(){
|
||||||
|
$('.asset_del').click(function(){
|
||||||
|
var row = $(this).closest('tr');
|
||||||
|
if (confirm("确定删除?")) {
|
||||||
|
$.get(
|
||||||
|
$(this).attr('value'),
|
||||||
|
{},
|
||||||
|
function (data) {
|
||||||
|
row.remove()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#exec_cmd').click(function(){
|
||||||
|
var url = '{% url "role_get" %}';
|
||||||
|
var new_url = '{% url "exec_cmd" %}?role=';
|
||||||
|
var check_array = [];
|
||||||
|
$(".gradeX input:checked").closest('tr').find('.hostname a').each(function() {
|
||||||
|
check_array.push($(this).text())
|
||||||
|
});
|
||||||
|
check_assets = check_array.join(':');
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: url,
|
||||||
|
data: {},
|
||||||
|
success: function(data){
|
||||||
|
var dataArray = data.split(',');
|
||||||
|
if (dataArray.length == 1 && data != 'error'){
|
||||||
|
var title = 'Jumpserver Exec Terminal';
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: title,
|
||||||
|
maxmin: true,
|
||||||
|
shade: false,
|
||||||
|
area: ['725px', '600px'],
|
||||||
|
content: new_url+data+'&check_assets='+check_assets
|
||||||
|
});
|
||||||
|
//window.open(new_url + data, '', 'location=no, resizeable=no, height=410, width=625, top=89px, left=99px,toolbar=no,menubar=no,scrollbars=auto,status=no');
|
||||||
|
} else if (dataArray.length == '1' && data == 'error'){
|
||||||
|
layer.alert('没有授权系统用户')
|
||||||
|
} else {
|
||||||
|
aUrl = '';
|
||||||
|
$.each(dataArray, function(index, value){
|
||||||
|
aUrl += '<a onclick="windowOpenExec(this); return false" class="btn btn-xs btn-primary newa" href=' + new_url + value + '&check_assets=' + check_assets + '>' + value + '</a> '
|
||||||
|
});
|
||||||
|
layer.alert(aUrl, {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
title: '授权多个系统用户,请选择一个连接',
|
||||||
|
shade: false,
|
||||||
|
closeBtn: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.conn').click(function(){
|
||||||
|
var url='{% url "role_get" %}?id=' + $(this).attr('value'); // 获取用户有权限的角色
|
||||||
|
var href = $(this).attr('href');
|
||||||
|
var new_url = '{% url "terminal" %}?id=' + $(this).attr('value') + '&role='; // webterminal socket url
|
||||||
|
var hostname = $(this).closest('tr').find('.hostname a')[0].innerHTML;
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: url,
|
||||||
|
data: {},
|
||||||
|
success: function(data){
|
||||||
|
var dataArray = data.split(',');
|
||||||
|
if (data == 'error' || data == '' || data == null || data == undefined){
|
||||||
|
layer.alert('没有授权系统用户')
|
||||||
|
}
|
||||||
|
else if (dataArray.length == 1 && data != 'error' && navigator.platform == 'Win32'){
|
||||||
|
/*
|
||||||
|
var title = 'Jumpserver Web Terminal' + '<span class="text-info"> '+ hostname +'</span>';
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: title,
|
||||||
|
maxmin: true,
|
||||||
|
shade: false,
|
||||||
|
area: ['628px', '420px'],
|
||||||
|
content: new_url+data
|
||||||
|
});
|
||||||
|
window.open(new_url+data, '_blank', 'toolbar=yes, location=yes, scrollbars=yes, resizable=yes, copyhistory=yes, width=628, height=400')
|
||||||
|
*/
|
||||||
|
window.open(new_url+data, "_blank");
|
||||||
|
} else if (dataArray.length == 1 && data != 'error'){
|
||||||
|
/*layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: title,
|
||||||
|
maxmin: true,
|
||||||
|
shade: false,
|
||||||
|
area: ['628px', '452px'],
|
||||||
|
content: new_url+data
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
window.open(new_url+data, '_blank');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
aUrl = '';
|
||||||
|
$.each(dataArray, function(index, value){
|
||||||
|
aUrl += '<a onclick="windowOpen(this); return false" class="btn btn-xs btn-primary newa" href=' + new_url + value + ' value=' + hostname + '>' + value + '</a> '
|
||||||
|
});
|
||||||
|
console.log(aUrl);
|
||||||
|
layer.alert(aUrl, {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
title: '授权多个系统用户,请选择一个连接',
|
||||||
|
shade: false,
|
||||||
|
closeBtn: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function windowOpen(a){
|
||||||
|
var new_url = $(a).attr('href');
|
||||||
|
var hostname = $(a).attr('value');
|
||||||
|
var title = 'Jumpserver Web Terminal - ' + '<span class="text-info"> '+ hostname +'</span>';
|
||||||
|
if (navigator.platform == 'Win32'){
|
||||||
|
/*
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: title,
|
||||||
|
maxmin: true,
|
||||||
|
area: ['628px', '420px'],
|
||||||
|
shade: false,
|
||||||
|
content: new_url
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
window.open(new_url, '_blank')
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: title,
|
||||||
|
maxmin: true,
|
||||||
|
area: ['628px', '452px'],
|
||||||
|
shade: false,
|
||||||
|
content: new_url
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
window.open(new_url, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function windowOpenExec(a){
|
||||||
|
var new_url = $(a).attr('href');
|
||||||
|
var title = 'Jumpserver Exec Terminal';
|
||||||
|
layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: title,
|
||||||
|
maxmin: true,
|
||||||
|
area: ['725px', '600px'],
|
||||||
|
shade: false,
|
||||||
|
content: new_url
|
||||||
|
});
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".iframe").on('click', function(){
|
||||||
|
var asset_id_all = getIDall();
|
||||||
|
if (asset_id_all == ''){
|
||||||
|
alert("请至少选择一行!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
var url= $(this).attr("value") + '?asset_id_all=' + asset_id_all;
|
||||||
|
parent.layer.open({
|
||||||
|
type: 2,
|
||||||
|
title: 'JumpServer - 批量修改主机',
|
||||||
|
maxmin: true,
|
||||||
|
shift: 'top',
|
||||||
|
border: [2, 0.3, '#1AB394'],
|
||||||
|
shade: [0.5, '#000000'],
|
||||||
|
area: ['800px', '600px'],
|
||||||
|
shadeClose: true,
|
||||||
|
content: url,
|
||||||
|
cancel: function(){
|
||||||
|
location.replace(location.href);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.search-btn-excel').unbind('click').bind('click',function(){
|
||||||
|
var url= $(this).attr("href");
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
data: $("#asset_form").serialize(),
|
||||||
|
success: function (data) {
|
||||||
|
$("#export").html(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
$('#asset_del').click(function () {
|
||||||
|
var asset_id_all = getIDall();
|
||||||
|
if (asset_id_all == ''){
|
||||||
|
alert("请至少选择一行!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (confirm("确定删除?")) {
|
||||||
|
$.ajax({
|
||||||
|
type: "post",
|
||||||
|
data: {asset_id_all: asset_id_all},
|
||||||
|
url: "{% url 'asset_del' %}?arg=batch",
|
||||||
|
success: function () {
|
||||||
|
parent.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#asset_update').click(function () {
|
||||||
|
var asset_id_all = getIDall();
|
||||||
|
if (asset_id_all == ''){
|
||||||
|
if (confirm("更新全部资产信息?")) {
|
||||||
|
layer.msg('玩命更新中...', {time: 200000});
|
||||||
|
$.ajax({
|
||||||
|
type: "post",
|
||||||
|
url: "{% url 'asset_update_batch' %}?arg=all",
|
||||||
|
success: function () {
|
||||||
|
parent.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
layer.msg('玩命更新中...', {time: 200000});
|
||||||
|
$.ajax({
|
||||||
|
type: "post",
|
||||||
|
data: {asset_id_all: asset_id_all},
|
||||||
|
url: "{% url 'asset_update_batch' %}",
|
||||||
|
success: function () {
|
||||||
|
parent.location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
{# $('#asset_update_all').click(function () {#}
|
||||||
|
{# layer.msg('玩命更新中...', {time: 200000});#}
|
||||||
|
{# $.ajax({#}
|
||||||
|
{# type: "post",#}
|
||||||
|
{# url: "/jasset/asset_update_batch/?arg=all",#}
|
||||||
|
{# success: function () {#}
|
||||||
|
{# parent.location.reload();#}
|
||||||
|
{# }#}
|
||||||
|
{# });#}
|
||||||
|
{# });#}
|
||||||
|
|
||||||
|
function change_info(){
|
||||||
|
var args = $("#asset_form").serialize();
|
||||||
|
window.location = "{% url 'asset_list' %}?" + args
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#search_input").keydown(function(e){
|
||||||
|
if(e.keyCode==13){
|
||||||
|
change_info()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -1 +1,12 @@
|
||||||
|
# coding:utf-8
|
||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
|
from .views import *
|
||||||
|
|
||||||
|
app_name = 'assets'
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^add/$', AssetAddView.as_view(), name='asset-add'),
|
||||||
|
url(r'^list/$', AssetListView.as_view(), name='asset-list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/delete/$', AssetDeleteView.as_view(), name='asset-list'),
|
||||||
|
url(r'^(?P<pk>[0-9]+)/detail/$', AssetDetailView.as_view(), name='asset-detail'),
|
||||||
|
]
|
||||||
|
|
|
@ -1,3 +1,54 @@
|
||||||
from django.shortcuts import render
|
from django.views.generic import (
|
||||||
|
TemplateView, ListView
|
||||||
|
)
|
||||||
|
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
|
|
||||||
|
from django.views.generic.edit import (
|
||||||
|
CreateView, DeleteView, FormView, UpdateView
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from django.views.generic.detail import (
|
||||||
|
DetailView
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from .models import (
|
||||||
|
Asset, AssetGroup, IDC, AssetExtend
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from .forms import (
|
||||||
|
AssetForm,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class AssetAddView(CreateView):
|
||||||
|
model = Asset
|
||||||
|
form_class = AssetForm
|
||||||
|
template_name = 'assets/asset_add.html'
|
||||||
|
success_url = reverse_lazy('assets:asset-list')
|
||||||
|
|
||||||
|
|
||||||
|
class AssetEdit():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class AssetDeleteView(DeleteView):
|
||||||
|
model = Asset
|
||||||
|
success_url = reverse_lazy('assets:asset-list')
|
||||||
|
|
||||||
|
|
||||||
|
class AssetListView(ListView):
|
||||||
|
model = Asset
|
||||||
|
context_object_name = 'assets'
|
||||||
|
template_name = 'assets/asset_list.html'
|
||||||
|
|
||||||
|
|
||||||
|
class AssetDetailView(DetailView):
|
||||||
|
model = Asset
|
||||||
|
context_object_name = 'asset'
|
||||||
|
template_name = 'assets/asset_detail.html'
|
||||||
|
|
||||||
# Create your views here.
|
|
||||||
|
|
|
@ -18,5 +18,6 @@ from django.conf.urls import url, include
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^users/', include('users.urls')),
|
url(r'^users/', include('users.urls')),
|
||||||
|
url(r'^assets/', include('assets.urls')),
|
||||||
# url(r'^admin/', admin.site.urls),
|
# url(r'^admin/', admin.site.urls),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Reference in New Issue