CMDB增删改查(基于form表单)
1. 设计表,在models中定义好字段
class Disk(models.Model):
'''磁盘'''
path = models.CharField(max_length=64, blank=True, null=True, verbose_name='挂载路径')
size = models.CharField(max_length=16, blank=True, null=True, verbose_name='磁盘大小/G')
remarks = models.CharField(max_length=2048, blank=True, null=True, verbose_name='备注')
def __str__(self):
return self.size
class Meta:
verbose_name_plural = "磁盘表"
class Region(models.Model):
name = models.CharField(max_length=64,blank=True,null=True,verbose_name='区域')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "区域表"
class Host(models.Model):
'''主机,阿里云eth0 内网网卡, eth1 公网网卡'''
hostname= models.CharField(max_length=64, blank=True, null=True, verbose_name='阿里云主机名')
ecsname= models.CharField(max_length=64, blank=True, null=True, verbose_name='阿里云实例ID')
logining=models.ManyToManyField(to='Login',blank=True, null=True, verbose_name='授权用户')
login_port = models.CharField(max_length=16, default='22',blank=True, null=True, verbose_name='ssh登录端口')
cpu= models.CharField(max_length=8,blank=True, null=True, verbose_name='CPU')
lab= models.ForeignKey(to='Lable',blank=True, null=True, verbose_name='标签')
mem= models.CharField(max_length=8,blank=True, null=True, verbose_name='内存/M')
# mem= models.ForeignKey(to='Memory',blank=True, null=True, verbose_name='内存/M')
speed = models.CharField(max_length=8,blank=True, default='5',null=True, verbose_name='带宽/M')
disks= models.ManyToManyField(to='Disk', blank=True, null=True, verbose_name='磁盘')
eth1_network= models.CharField(max_length=32, blank=True, null=True, verbose_name='公网IP')
eth0_network= models.CharField(max_length=32,verbose_name='私网IP')
sn= models.CharField(max_length=64, blank=True, null=True, verbose_name='sn')
os= models.ForeignKey(to='Os', blank=True, null=True, verbose_name='操作系统') #os+版本号
kernel= models.CharField(max_length=64, blank=True, null=True, verbose_name='系统内核') #内核+版本号
the_upper=models.ForeignKey(to='Host',blank=True,null=True,verbose_name='宿主机',related_name='upper')
source=models.ForeignKey(to='Source',blank=True,null=True,verbose_name='来源类型')
region=models.ForeignKey(to='Region',blank=True,null=True,verbose_name='所属区域')
remarks = models.CharField(max_length=2048, blank=True, null=True, verbose_name='备注')
createtime = models.CharField(max_length=32, blank=True, null=True, verbose_name='创建时间')
expirytime = models.CharField(max_length=32, blank=True, null=True, verbose_name='到期时间')
vpcnet = models.ForeignKey(to='VpcNet', blank=True, null=True, verbose_name='VPC网络',related_name='vpcnet')
vpcsw = models.ForeignKey(to='VpcSwitch', blank=True, null=True, verbose_name='VPC交换机')
vpccon = models.ForeignKey(to='VpcNet', blank=True, null=True, verbose_name='VPC连接',related_name='vpccon')
state_choices=(
(1,'Running'),
(2,'下线'),
(3,'关机'),
(4,'删除'),
)
state = models.SmallIntegerField(verbose_name='主机状态', choices=state_choices,blank=True,null=True,)
def __str__(self):
return self.eth0_network
class Meta:
verbose_name_plural = "主机表"
class Login(models.Model):
'''登录相关'''
login_name = models.CharField(max_length=16, default='root', verbose_name='登录用户名')
login_pwd= models.CharField(max_length=64, blank=True, null=True, verbose_name='登录密码')
auth=models.CharField(max_length=8,blank=True, null=True, verbose_name='具有权限')
def __str__(self):
return self.login_name
class Meta:
verbose_name_plural = "主机用户表"
class Source(models.Model):
'''来源:阿里云、物理机(某机房等)'''
name = models.CharField(max_length=16, blank=True, null=True, verbose_name='来源')
def __str__(self):
return self.name
class Meta:
verbose_name_plural = "主机来源表"
python manage.py makemigrations
python manage.py migrate
2. 设计路由,增删改查分别走路径
- 这里我们让增删改查走一个app,所以使用include引入:
from django.conf.urls import url,include
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include('apiAPP.urls')),
]
from django.conf.urls import url,include
from django.contrib import admin
from apiAPP import views
'''任何usl都会从这里匹配'''
'''此处是精确匹配,写list.html,浏览器也要写list.html,后面带/的话,浏览器也要带/'''
urlpatterns = [
url(r'^list$', views.List.as_view()),
url(r'^update/(\d+)/', views.Update.as_view()),
url(r'^add$', views.Add.as_view()),
url(r'^del', views.Del.as_view()),
]
3. 利用Form表单来在前端展现数据:
- 这里我们创建一个跟应用app同级的目录,utils,并且创建
- form_class.py:
#!/usr/bin/python
# -*- coding:utf-8 -*-
# @Time : 2019/1/16 14:33
# @Author : liaochao
# @File : form_class.py
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from apiAPP import models
class HostForm(Form):
hostname = fields.CharField(
required=True,
#error_messages={'required': '不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
cpu = fields.IntegerField(
required=True,
#error_messages={'required': '不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
mem = fields.IntegerField(
required=True,
#error_messages={'required': '不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
speed = fields.CharField(
required=True,
#error_messages={'required': '不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
eth0_network = fields.CharField(
required=True,
#error_messages={'required': '不能为空'},
widget=widgets.TextInput(attrs={'class': 'form-control'})
)
# state = fields.ChoiceField(
# required=True,
# # values_list('id','name') 会让数据变成[(id,name),(id,name)] 这种格式
# choices=[],
# #下拉框
# widget=widgets.Select(attrs={'class': 'form-control'}),
# )
source_id = fields.ChoiceField(
required=True,
# values_list('id','name') 会让数据变成[(id,name),(id,name)] 这种格式
choices=[],
#下拉框
widget=widgets.Select(attrs={'class': 'form-control'}),
)
region_id = fields.ChoiceField(
required=True,
choices=[],
widget=widgets.Select(attrs={'class': 'form-control'})
)
def __init__(self,*args,**kwargs):
'每次都默认执行初始化,保证在数据库拿到的数据是最新的'
super(HostForm,self).__init__(*args,**kwargs)
# values_list('id','name') 会让数据变成[(id,name),(id,name)] 这种格式
self.fields['source_id'].choices = models.Source.objects.values_list('id','name')
self.fields['region_id'].choices=models.Region.objects.values_list('id','name')
# self.fields['state'].choices=models.Host.objects.values_list('id','state')
4. 我们在apiAPP里面的viwe.py里面写增删改查逻辑
from django.shortcuts import render,HttpResponse,redirect
from apiAPP import models
from django.views import View
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from utils import form_class
# Create your views here.
class List(View):
def post(self,request,*args,**kwargs):
pass
def get(self,request,*args,**kwargs):
# return HttpResponse('List')
host_list=models.Host.objects.all()
return render(request,'host.html',locals())
class Add(View):
'''基于form的增加'''
def post(self,request,*args,**kwargs):
form =form_class.HostForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
models.Host.objects.create(**form.cleaned_data)
print("正常提交")
return redirect('/api/list')
else:
print(form.errors)
return render(request,'add.html',locals())
def get(self,request,*args,**kwargs):
form = form_class.HostForm()
return render(request,'add.html',locals())
class Update(View):
'''基于form的修改'''
def post(self,request,pk):
print("post--id-->", pk)
form = form_class.HostForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data)
models.Host.objects.filter(id=pk).update(**form.cleaned_data)
return redirect('/api/list')
else:
print(form.errors)
return render(request,'edit.html',locals())
def get(self,request,pk):
print ("get--id-->",pk)
# # 拿到前端传过来的id
# get_id = request.GET.get('id')
obj = models.Host.objects.filter(id=pk).first()
print(obj)
form = form_class.HostForm(
initial={
'hostname':obj.hostname,
'cpu':obj.cpu,
'mem':obj.mem,
'speed':obj.speed,
'eth0_network':obj.eth0_network,
'source_id':obj.source_id,
'region_id':obj.region_id,
# 'get_state_display ':obj.get_state_display ,
}
)
# return HttpResponse('update')
return render(request,'edit.html',locals())
class Del(View):
def post(self,request,*args,**kwargs):
pass
def get(self,request,*args,**kwargs):
get_id = int(request.GET.get('id'))
models.Host.objects.filter(id=get_id).delete()
return redirect('/api/list')
5. 编写tempates中的html,用于前端展示
- 其中我们需要一个list展示的host.html,增加的add.html,编辑的edit.html。
- host.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主机列表</title>
</head>
<body>
<div>
<a href="/api/add">添加</a>
</div>
<div class="container">
<table class="table table-bordered table-hover" id="table">
<thead>
<tr>
<th> </th>
<th>主机名</th>
<th>CPU</th>
<th>内存/G</th>
<th>带宽/M</th>
<th>IP</th>
<th>来源类型</th>
<th>所属区域</th>
<th>状态</th>
<th>编辑</th>
<th>删除</th>
</tr>
</thead>
<tbody>
{% for host in host_list %}
<tr>
<td>{{ host.id }}</td>
<td>{{ host.hostname }}</td>
<td>{{ host.cpu }}</td>
<td>{{ host.mem }}</td>
<td>{{ host.speed }}</td>
<td>{{ host.eth0_network }}</td>
<td>{{ host.source.name }}</td>
<td>{{ host.region.name }}</td>
<td>{{ host.get_state_display }}</td>
<td><a href="/api/update/{{ host.id }}">编辑</a></td>
<td><a href="/api/del?id={{ host.id }}">删除</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主机添加</title>
</head>
<body>
<form class="form-horisontal templatemo-container templatemo-login-form-1 margin-bottom-30" method="post" novalidate role="form">
{% csrf_token %}
<p id="hostname">主机名:{{ form.hostname }} {{form.errors.hostname.0 }}</p>
<p id="cpu">cpu:{{ form.cpu }} {{ form.errors.cpu.0 }}</p>
<p id="mem">内存:{{ form.mem }} {{ form.errors.mem.0 }}</p>
<p id="speed">带宽:{{ form.speed }} {{ form.errors.speed.0 }}</p>
<p id="eth0_network">网卡ip:{{ form.eth0_network }} {{ form.errors.eth0_network }}</p>
<p id="source.name">来源:{{ form.source_id }}</p>
<p id="region.name">区域:{{ form.region_id }}</p>
<input type="submit" value="提交">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数据编辑</title>
</head>
<body>
<form class="form-horisontal templatemo-container templatemo-login-form-1 margin-bottom-30" method="post" novalidate role="form">
{% csrf_token %}
<p id="hostname">主机名:{{ form.hostname }} {{form.errors.hostname.0 }}</p>
<p id="cpu">cpu:{{ form.cpu }} {{ form.errors.cpu.0 }}</p>
<p id="mem">内存:{{ form.mem }} {{ form.errors.mem.0 }}</p>
<p id="speed">带宽:{{ form.speed }} {{ form.errors.speed.0 }}</p>
<p id="eth0_network">网卡ip:{{ form.eth0_network }} {{ form.errors.eth0_network }}</p>
<p id="source.name">来源:{{ form.source_id }}</p>
<p id="region.name">区域:{{ form.region_id }}</p>
<input type="submit" value="提交">
</body>
</html>
网友评论