在上一篇,我们已经把我们做的运维外面套上了bootstrap框架,但是那仅仅是一个外壳,这一次是要把里面的壤也扣上这样的框架。
首先,编辑index.html,添加block元素,用于主页存放不同的内容:
<div class="page-content">
<div class="page-content-area">
<div class="page-header">
<h1>
<!--设置导航栏的页面标题-->
{% block page_title %}
{% endblock %}
<small>
<i class="ace-icon fa fa-angle-double-right"></i>
<!--设置导航栏的页面子标题-->
{{ sub_title }}
</small>
</h1>
</div><!-- /.page-header -->
<div class="row">
<div class="col-xs-12">
<!-- PAGE CONTENT BEGINS -->
<!--设置页面内容-->
{% block container %}
{% endblock %}
<!-- PAGE CONTENT ENDS -->
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.page-content-area -->
</div><!-- /.page-content -->之前在models.py里我们设定了很多个项目,比如alionlineECS,alifuncECS等等,那么对应每一个项目都会有一个html,在这里我命名:alionlineECS_list.html用于存放“阿里云线上环境服务器”信息,alifuncECS_list.html用于“阿里云测试环境服务器”信息,ksonlineECS_list.html用于存放“金山云线上环境服务器”信息,ksfuncECS_list.html用于“金山云测试环境服务器”信息,同时修改index.html中Table下的链接,将其中的链接指向上面那些html们:
<ul class="submenu">
<li class="">
<a href="{% url ‘lists‘ table=‘alionlineECS‘ %}">
<i class="menu-icon fa fa-caret-right"></i>
阿里云线上环境服务器
</a>
<b class="arrow"></b>
</li>
<li class="">
<a href="{% url ‘lists‘ table=‘alifuncECS‘ %}">
<i class="menu-icon fa fa-caret-right"></i>
阿里云测试环境服务器
</a>
<b class="arrow"></b>
</li>
<li class="">
<a href="{% url ‘lists‘ table=‘ksonlineECS‘ %}">
<i class="menu-icon fa fa-caret-right"></i>
金山云线上环境服务器
</a>
<b class="arrow"></b>
<li class="">
<a href="{% url ‘lists‘ table=‘ksfuncECS‘ %}">
<i class="menu-icon fa fa-caret-right"></i>
金山云测试环境服务器
</a>
<b class="arrow"></b>
</li>
</ul>建立res_list.html放在之前的template文件夹里,用来存放资源类表格,并把它作为一个模板,供其他页面继承,这样可以节省大量的重复代码。
<!--继承index.html-->
{% extends "index.html" %}
{% block page_css %}
{% endblock %}
<!--填充导航栏的页面名称-->
{% block page_title %}
基础资料
{% endblock %}
<!--放置主页面内容-->
{% block container %}
{% load staticfiles %}
<div class="row">
<!-- Search Page BEGINS-->
<div class="col-xs-12">
<form class="navbar-for navbar-container" role="search" method="get" action="">{% csrf_token %}
<!--放置搜索栏内容-->
{% block search %}
{% endblock %}
<div class="col-sm-3">
<span class="input-group-btn">
<button type="submit" class="btn btn-purple btn-sm">
查询
<i class="ace-icon fa fa-search icon-on-right bigger-110"></i>
</button>
</span>
</div>
</form>
</div>
<!-- Search Page END -->
<!-- PAGE TABLES BEGINS -->
<div class="col-xs-12">
<div>
<table id="table_id" class="table table-striped table-bordered table-hover">
<thead>
<!--表格头部-->
{% block table_tr %}
{% endblock %}
<th>
<!--最后一列作为添加数据按钮-->
<a class="blue" href="{% url ‘add‘ table=table %}">
<i class="ace-icon fa fa-search-plus bigger-130"></i>
添加数据
</a>
</th>
</thead>
<!--表格内容-->
<tbody>
{% for item in data %}
<tr>
<!--通过for循环从data取出的具体表格内容-->
{% block table_td %}
{% endblock %}
<td>
<!--页面扩展时的按钮布局-->
<div class="hidden-sm hidden-xs action-buttons">
<!--编辑信息按钮-->
<a class="green" href="{% url ‘edit‘ table item.id %}" title="编辑信息">
<i class="ace-icon fa fa-pencil bigger-130"></i>
</a>
<!--删除信息按钮-->
<a class="red" href="{% url ‘delete‘ table item.id %}" title="删除信息">
<i class="ace-icon fa fa-trash-o bigger-130"></i>
</a>
</div>
<!--页面收缩时的按钮布局-->
<div class="hidden-md hidden-lg">
<div class="inline position-relative">
<button class="btn btn-minier btn-yellow dropdown-toggle" data-toggle="dropdown"
data-position="auto">
<i class="ace-icon fa fa-caret-down icon-only bigger-120"></i>
</button>
<ul class="dropdown-menu dropdown-only-icon dropdown-yellow dropdown-menu-right dropdown-caret dropdown-close">
<li>
<a href="{% url ‘add‘ table=table %}" class="tooltip-info" data-rel="tooltip" title="添加数据">
<span class="blue">
<i class="ace-icon fa fa-search-plus bigger-120"></i>
</span>
</a>
</li>
<li>
<a href="{% url ‘edit‘ table item.id %}" class="tooltip-success" data-rel="tooltip" title="修改信息">
<span class="green">
<i class="ace-icon fa fa-pencil-square-o bigger-120"></i>
</span>
</a>
</li>
<li>
<a href="{% url ‘delete‘ table item.id %}" class="tooltip-error" data-rel="tooltip" title="删除信息">
<span class="red">
<i class="ace-icon fa fa-trash-o bigger-120"></i>
</span>
</a>
</li>
</ul>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
{% endblock %}
{% block page_javascript %}
<!--datatable的专用js-->
<script type="text/javascript">
$(document).ready(function () {
$(‘#table_id‘).DataTable({
//分页配置
"paging": false,
//搜索配置
"searching": false,
"bInfo": false,
//列配置
"columnDefs": [{
//只有最后一行不需要排序
"orderable": false, "targets": -1
}]
});
});
</script>
{% endblock %}alionlineECS_list.html,alifuncECS_list.html,slb_list.html等html文件继承res_list.html,并将各自不一样的内容在相应的block中进行填充,比如alionlineECS_list.html就是下面的样子:
{% extends "res_list.html" %}
{% block search %}
{% endblock %}
{% block table_tr %}
<th>云服务器名称</th>
<th>云服务器类型</th>
<th>云服务器内网地址</th>
<th>云服务器外网地址</th>
<th>云服务器外网带宽</th>
<th>云服务器配置</th>
<th>备注</th>
<th>登记人</th>
{% endblock %}
{% block table_td %}
<td>{{ item.ecs_name }}</td>
<td>{{ item.ecs_type }}</td>
<td>{{ item.ecs_inip }}</td>
<td>{{ item.ecs_outip }}</td>
<td>{{ item.ecs_ipwidth }}</td>
<td>{{ item.ecs_spec }}</td>
<td>{{ item.ecs_remarks }}</td>
<td>{{ item.ecs_signer }}</td>
{% endblock %}而slb_list.html就是这样:
{% extends "res_list.html" %}
{% block search %}
{% endblock %}
{% block table_tr %}
<th>负载均衡名称</th>
<th>网络类型</th>
<th>转发规则</th>
<th>ip地址</th>
<th>负载均衡协议</th>
<th>前端端口</th>
<th>后端端口</th>
<th>负载均衡协议</th>
<th>前端端口</th>
<th>后端端口</th>
<th>登记人</th>
<th>备注</th>
{% endblock %}
{% block table_td %}
<td>{{ item.slb_name }}</td>
<td>{{ item.slb_type }}</td>
<td>{{ item.slb_algorithm }}</td>
<td>{{ item.slb_ip }}</td>
<td>{{ item.slb_protocol }}</td>
<td>{{ item.slb_fport }}</td>
<td>{{ item.slb_bport }}</td>
<td>{{ item.slb_protocol2 }}</td>
<td>{{ item.slb_fport2 }}</td>
<td>{{ item.slb_bport2 }}</td>
<td>{{ item.slb_signer }}</td>
<td>{{ item.slb_remarks }}</td>
{% endblock %}rds_list.html的代码如下:
{% extends "res_list.html" %}
{% block search %}
{% endblock %}
{% block table_tr %}
<th>数据库名称</th>
<th>数据库类型</th>
<th>mysql版本</th>
<th>数据库规格</th>
<th>备注</th>
<th>数据库地址</th>
<th>存储空间</th>
<th>登记人</th>
{% endblock %}
{% block table_td %}
<td>{{ item.rds_name }}</td>
<td>{{ item.rds_type }}</td>
<td>{{ item.rds_mysql }}</td>
<td>{{ item.rds_spec }}</td>
<td>{{ item.rds_remark }}</td>
<td>{{ item.rds_ip }}</td>
<td>{{ item.rds_status }}</td>
<td>{{ item.rds_signer }}</td>
{% endblock %}网页代码都准备好了,再往下的内容是修改views.py,把lists那个函数改成这样:
def lists(request,table):
#不同的需求跳到不同的界面
if table == ‘alionlineECS‘:
data = alionlineECS.objects.all()
list_template = ‘alionlineECS_list.html‘
sub_title = ‘阿里云线上环境服务器‘
if table == ‘alifuncECS‘:
data = alifuncECS.objects.all()
list_template = ‘alifuncECS_list.html‘
sub_title = ‘阿里云测试环境服务器‘
if table == ‘ksonlineECS‘:
data = ksonlineECS.objects.all()
list_template = ‘ksonlineECS_list.html‘
sub_title = ‘金山云线上环境服务器‘
if table == ‘ksfuncECS‘:
data = ksfuncECS.objects.all()
list_template = ‘ksfuncECS_list.html‘
sub_title = ‘金山云线上环境服务器‘
if table == ‘SLB‘:
data = SLB.objects.all()
list_template = ‘slb_list.html‘
sub_title = ‘负载均衡‘
if table == ‘RDS‘:
data = RDS.objects.all()
list_template = ‘rds_list.html‘
sub_title = ‘数据库‘
#建立一个context,将值传递到对应的页面
context = {
‘data‘: data,
‘table‘: table,
‘sub_title‘: sub_title,
}
#跳转到相应页面,并将具体的值传递过去
return render(request,list_template,context)add的函数应该是这样:
def add(request,table):
#根据提交的请求不同,获取来自不同Form的表单数据
if table == ‘alionlineECS‘:
form = alionlineForm(request.POST or None)
if table == ‘alifuncECS‘:
form = alifuncForm(request.POST or None)
if table == ‘ksonlineECS‘:
form = ksonlineForm(request.POST or None)
if table == ‘ksfuncECS‘:
form = ksfuncForm(request.POST or None)
if table == ‘SLB‘:
form = SLBForm(request.POST or None)
if table == ‘RDS‘:
form = RDSForm(request.POST or None)
#判断form是否有效
if form.is_valid():
#创建实例,需要做些数据处理,暂不做保存
instance = form.save(commit=False)
#将登录用户作为登记人
if table == ‘alionlineECS‘:
instance.ecs_signer = request.user
if table == ‘alifuncECS‘:
instance.ecs_signer = request.user
if table == ‘ksonlineECS‘:
instance.ecs_signer = request.user
if table == ‘ksfuncECS‘:
instance.ecs_signer = request.user
if table == ‘SLB‘:
instance.slb_signer = request.user
if table == ‘RDS‘:
instance.rds_signer = request.user
#保存该实例
instance.save()
#跳转至列表页面
return redirect(‘lists‘,table=table)
#创建context来集中处理需要传递到页面的数据
context = {
‘form‘: form,
‘table‘: table,
}
#如果没有有效提交,则仍留在原来页面
return render(request,‘add.html‘,context)同时,我们要添加两个新的函数,一个叫edit,他的内容如下:
#修改数据,函数中的pk代表数据的id
def edit(request,table,pk):
if table == ‘alionlineECS‘:
#这是Django的一个快捷方法,通过pk去line表中取值,如果有值则返回,如果无值则抛出http404的异常
#具体信息可参考https://docs.djangoproject.com/en/1.9/topics/http/shortcuts/
table_ins = get_object_or_404(alionlineECS,pk=pk)
#通过instance来将Form的数据做填充
form = alionlineForm(request.POST or None,instance=table_ins)
sub_title = ‘修改阿里云线上环境信息‘
if table == ‘alifuncECS‘:
table_ins = get_object_or_404(alifuncECS,pk=pk)
form = alifuncForm(request.POST or None,instance=table_ins)
sub_title = ‘修改阿里云线上环境信息‘
if table == ‘ksonlineECS‘:
table_ins = get_object_or_404(ksonlineECS,pk=pk)
form = ksonlineForm(request.POST or None,instance=table_ins)
sub_title = ‘修改金山云线上环境服务器信息‘
if table == ‘ksfuncECS‘:
table_ins = get_object_or_404(ksfuncECS,pk=pk)
form = ksfuncForm(request.POST or None,instance=table_ins)
sub_title = ‘修改金山云测试环境服务器信息‘
if table == ‘SLB‘:
table_ins = get_object_or_404(SLB,pk=pk)
form = SLBForm(request.POST or None,instance=table_ins)
sub_title = ‘修改负载均衡信息‘
if table == ‘RDS‘:
table_ins = get_object_or_404(RDS,pk=pk)
form = RDSForm(request.POST or None,instance=table_ins)
sub_title = ‘修改数据库信息‘
#判断form是否有效
if form.is_valid():
#创建实例,需要做些数据处理,暂不做保存
instance = form.save(commit=False)
#将登录用户作为登记人,在修改时,一定要使用str强制
if table == ‘alionlineECS‘:
instance.ecs_signer = str(request.user)
if table == ‘alifuncECS‘:
instance.ecs_signer = str(request.user)
if table == ‘ksonlineECS‘:
instance.ecs_signer = str(request.user)
if table == ‘ksfuncECS‘:
instance.ecs_signer = str(request.user)
if table == ‘SLB‘:
instance.slb_signer = str(request.user)
if table == ‘RDS‘:
instance.rds_signer = str(request.user)
#保存该实例
instance.save()
#跳转至列表页面,配合table参数,进行URL的反向解析
return redirect(‘lists‘, table=table)
context = {
‘table‘: table,
‘form‘: form,
‘page_title‘: ‘基础资料‘,
‘sub_title‘: sub_title,
}
#与res_add.html用同一个页面,只是edit会在res_add页面做数据填充
return render(request,‘res_add.html‘,context)另一个函数是delete,这个是用来删除的,内容如下:
#删除操作 def delete(request,table,pk): #选择相应的表格 if table == ‘alionlineECS‘: #通过id值获取相应表格的实例,有值则返回,无值则抛出异常 table_ins = get_object_or_404(alionlineECS,pk=pk) if table == ‘alifuncECS‘: table_ins = get_object_or_404(alifuncECS,pk=pk) if table == ‘ksonlineECS‘: table_ins = get_object_or_404(ksonlineECS,pk=pk) if table == ‘ksfuncECS‘: table_ins = get_object_or_404(ksfuncECS,pk=pk) if table == ‘SLB‘: table_ins = get_object_or_404(SLB,pk=pk) if table == ‘RDS‘: table_ins = get_object_or_404(RDS,pk=pk) #接收通过AJAX提交过来的POST if request.method == ‘POST‘: #删除该条目 try: table_ins.delete() #删除成功,则data信息为success data = ‘success‘ except IntegrityError: #如因外键问题,或其他问题,删除失败,则报error data = ‘error‘ #将最后的data值传递至JS页面,进行后续处理,safe是将对象序列化,否则会报TypeError错误 return JsonResponse(data,safe=False)
别忘了这里还要修改一下主urls.py,添加edit和delete:
from django.conf.urls import url,include from django.contrib import admin import Online.views admin.autodiscover() from Online import views as Online_views urlpatterns = [ url(r‘^admin/‘,admin.site.urls), url(r‘^lists/(?P<table>\w+)/$‘,Online.views.lists,name=‘lists‘), url(r‘^add/(?P<table>\w+)/$‘,Online.views.add,name=‘add‘), #基础资料的显示 #修改数据,?P<pk>\d+代表穿过来的id值,且id值一定为数字 url(r‘^edit/(?P<table>\w+)/(?P<id>\d+)/$‘,Online.views.edit,name=‘edit‘), #删除数据 url(r‘^delete/(?P<table>\w+)/(?P<pk>\d+)/$‘,Online.views.delete,name=‘delete‘), url(r‘^index/‘,Online.views.index,name=‘index‘), url(r‘^login/‘,include(‘Online.urls‘)), ]
启动django,在浏览器里输入"外网地址:8000/lists/slb"就发现原来那个白色的界面已经运用了boostrap模板,如下:
而打开"外网地址:8000/lists/alionlineECS",对应阿里区线上环境的资料也是套用了boostrap模板:
当你点击“添加数据”的时候,界面也是会正确转向的:
但是这个增加的页面很难看,白白的底儿,很挫,我们也希望这个增加的界面也有模板的样子。于是这里要用一个django-crispy-forms的app,首先在服务器里,使用#pip install --upgrade django-crispy-forms下载并安装。
然后在settings.py中加入相关app,并使其使用bootstrap3的前端。修改settings.py如下:
INSTALLED_APPS = [ ‘django.contrib.admin‘, ‘django.contrib.auth‘, ‘django.contrib.contenttypes‘, ‘django.contrib.sessions‘, ‘django.contrib.messages‘, ‘django.contrib.staticfiles‘, ‘Online‘, ‘SLB‘, ‘RDS‘, #crispy app 把这个APP添加进去 ‘crispy_forms‘, ]
然后还要在settings.py后面追加下面一句话:
#App settings CRISPY_TEMPLATE_PACK = ‘bootstrap3‘
再修改add.html文件,把crispy.form应用进去:
<!--引用crispy-forms标签-->
{% load crispy_forms_tags %}
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form method=‘POST‘ action=‘‘>{% csrf_token %}
<!--将crispy-forms应用到form中-->
{{ form | crispy }}
<input type=‘submit‘ value=‘提交‘ />
</form>
</body>
</html>然后再返回来看看添加的界面,嗯,好像变样了:
我们现在为了统一,把add.html改成res_add.html,同时继承index.html,将res_add.html中的内容填充到index的Container block。
{% extends "index.html" %}
<!--引用crispy-forms标签-->
{% load crispy_forms_tags %}
{% block page_title %}
基础资料
{% endblock %}
{% block container %}
<div class="row">
<div class="col-sm-3 pull-left">
<form method=‘POST‘ action=‘‘>{% csrf_token %}
<!--将crispy-forms应用到form中-->
{{ form | crispy}}
<input class=‘btn btn-primary‘ type=‘submit‘ value=‘提交‘ />
<a href="{% url ‘lists‘ table=table %} "><input class=‘btn btn-default‘ type=‘button‘ value=‘取消‘ /></a>
</form>
</div>
</div>
{% endblock %}然后再把views.py里面add函数里面最后那一行
return render(request,‘add.html‘,context)
改成
return render(request,‘res_add.html‘,context)
至此,整个添加界面就全部继承过来了:
本文出自 “生活就是等待戈多” 博客,请务必保留此出处http://chenx1242.blog.51cto.com/10430133/1952685
Django运维后台的搭建之五:引入databases和django-crispy-forms
原文地址:http://chenx1242.blog.51cto.com/10430133/1952685