效果
主要分三个部分进行介绍
界面设计;动态渲染;数据获取
(1)将这个界面分为上部导航栏、左侧导航栏和表格显示区域三部分;
我们期望的结果是通过点击左侧导航栏的选项,在右侧动态展示不同信息, 这里我们使用iframe来实现。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Managetitle>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js">script>
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js">script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js">script>
head>
<body>
<iframe height="50px" width="100%" id="top" src="{% url 'top' %}">iframe>
<iframe height="600px" width="15%" id="left" src="{% url 'left' %}">iframe>
<iframe height="600px" width="83%" id="right" name="show">iframe>
body>
html>
定义三个iframe:left、top和right,设置每个frame的高和宽,达到上面的布局,这里不再详细阐述,可以看上方代码。
(2)编写相应三个iframe对应网页
top和left主要是编写导航栏,可以直接搜索bootstrap的导航栏,选择自己喜欢的样式复制过来即可。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Managetitle>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js">script>
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js">script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js">script>
head>
<body>
<iframe height="50px" width="100%" id="top" src="{% url 'top' %}">iframe>
<iframe height="600px" width="15%" id="left" src="{% url 'left' %}">iframe>
<iframe height="600px" width="83%" id="right" name="show">iframe>
body>
html>
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Toptitle>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js">script>
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js">script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js">script>
head>
<body>
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed"
data-toggle="collapse" data-target="#demo-navbar">
<span class="sr-only">Toggle navigationspan>
<span class="icon-bar">span>
<span class="icon-bar">span>
<span class="icon-bar">span>
button>
<a class="navbar-brand" href="#">管理系统a>
div>
body>
html>
本文选用a标签设计导航栏,通过href实现点击跳转动作,{% url ‘student_manage’ %}表示跳转的路由,在urls中定义了和该路由绑定的视图函数,当然也可以写成静态HTML。target表示点击该标签后,请求路由,并将请求到的信息在target上显示,这里target=‘show’,在manage中定义了right iframe的名字是show。也就是说当点击标签后,进行跳转,将请求到的信息在right的iframe中显示。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Lefttitle>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js">script>
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js">script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js">script>
head>
<body>
<div class="list-group">
<a href="{% url 'student_manage' %}" class="list-group-item" target="show">学生管理a>
<a href="{% url 'book_manage' %}" class="list-group-item" target="show">图书管理a>
<a href="{% url 'comment_manage' %}" class="list-group-item" target="show">评论管理a>
<a href="{% url 'record_manage' %}" class="list-group-item" target="show">记录管理a>
<a href="{% url 'advise_manage' %}" class="list-group-item" target="show">建议栏a>
div>
body>
html>
接下来需要编写我们需要管理的各种信息界面,对应左侧导航栏中的每个选择,这里以图书管理为例,编写book_manage.html
DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js">script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"5>script>
<link rel="stylesheet" href="https://unpkg.com/bootstrap-table@1.15.3/dist/bootstrap-table.min.css">
<script src="https://unpkg.com/bootstrap-table@1.15.3/dist/bootstrap-table.min.js">script>
<script src="https://unpkg.com/bootstrap-table@1.15.3/dist/locale/bootstrap-table-zh-CN.min.js">script>
head>
<body>
<div id="panel-group" >
<div class="panel-body">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title">图书信息管理h3>
div>
<div class="panel-body">
<div style="display:inline-block;">
<div style="float:left;padding:6px;">
<span>查询内容:span>
div>
<div style="float:left;">
<input id="input" class="form-control" style="width:200px;" placeholder="请输入" />
div>
<div style="float:left;padding:6px;">
<span>查询条件:span>
div>
<div style="float:left;">
<select id="select" class="form-control" style="width:200px;">
<option value="">请选择option>
<option value="b_id">书号option>
<option value="b_isbn">ISBNoption>
<option value="b_pub">出版社option>
<option value="a_id">作者option>
<option value="b_category">类别option>
<option value="b_score">评分option>
select>
div>
<div style="float:left;margin-left:20px;">
<button id="query" class="btn btn-primary" onclick="search()">查询button>
div>
<div style="float:left;margin-left:20px;">
<button id="reset" class="btn btn-primary" onclick="reset()">重置button>
div>
div>
div>
div>
<div style="width: 95%;margin-bottom: 10%;margin-right: 20px;margin-left: 20px;">
<table id="table" >table>
div>
div>
body>
html>
使用boostrap-table显示各种信息,在使用时,引入bootstrap和bootstrap-table相关的js和css文件,只需要定义一个table,即
。表信息的初始化在JS代码中实现。
在JS中定义表头,请求路由,后端返回数据,在前端表中显示出来;
1、queryParams之前定义一些参数信息,重要的参数有
(1)请求路由url
(2)请求参数method,一般是get和post,默认为get
(3)pageNumber: 1 从第几页开始显示
(4)pageSize: 8 每页显示多少行
(5)sidePagination: “server”, //分页方式:client客户端分页,server服务端分页(*)
(6)queryParamsType : “limit”,设置为 ‘limit’ 则会发送符合 RESTFul 格式的参数。
2、queryParams: function (params)
在这个函数里,可以自定义参数传递到后端,比如我们设计的查询内容和查询条件,以字典的形式传递到后端进行处理
3、columns定义表头,里面主要包含三个元素
(1)field: 相当于这个字段的ID,这个要和后端传递过来的键值匹配,才能正确显示内容
(2)title: 表头显示的内容
(3)align: ‘center’, 表格对齐方式
<script type="text/javascript">
$(function () {
load('/info/')
});
function load(url){
$('#table').bootstrapTable({
url: url, // 请求数据源的路由
dataType: "json",
method: 'post',
pagination: true, //前端处理分页
singleSelect: false,//是否只能单选
search: false, //显示搜索框,此搜索是客户端搜索,不会进服务端,所以,个人感觉意义不大
toolbar: '#toolbar', //工具按钮用哪个容器
striped: true, //是否显示行间隔色
cache: false, //是否使用缓存,默认为true,所以一般情况下需要设置一下这个属性(*)
pageNumber: 1, //初始化加载第10页,默认第一页
pageSize: 8, //每页的记录行数(*)
pageList: [8, 20, 50, 100], //可供选择的每页的行数(*)
strictSearch: true,//设置为 true启用 全匹配搜索,false为模糊搜索
showColumns: false, //显示内容列下拉框
showRefresh: false, //显示刷新按钮
minimumCountColumns: 2, //当列数小于此值时,将隐藏内容列下拉框
clickToSelect: true, //设置true, 将在点击某行时,自动勾选rediobox 和 checkbox
uniqueId: "id", //每一行的唯一标识,一般为主键列
showToggle: false, //是否显示详细视图和列表视图的切换按钮
cardView: false, //是否显示详细视图
sidePagination: "server", //分页方式:client客户端分页,server服务端分页(*)
queryParamsType : "limit",//设置为 ‘limit’ 则会发送符合 RESTFul 格式的参数.
queryParams: function (params) {//自定义参数,这里的参数是传给后台的
var data = {
size: params.limit, //页面大小
current: (params.offset / params.limit) + 1, //页码
content:$('#input').val(),
condition:$('#select').val(),
table_name:'Book',
};
return data;
},
responseHandler: function (res) {
//如果后台返回的json格式不是{rows:[{...},{...}],total:100},可以在这块处理成这样的格式
return res;
},
columns: [{ //定义表头,这个表头必须定义,下边field后边跟的字段名字必须与后端传递的字段名字相同.如:id、name、price 跟后端的字段名id name price是完全一样的.
checkbox: true,
visible: true
}, {
field: 'b_id',
title: '书号',
align: 'center', //对齐方式,居中
}, {
field: 'b_isbn',
title: 'ISBN',
align: 'center'
}, {
field: 'b_pub',
title: '出版社',
align: 'center'
}, {
field: 'b_date',
title: '出版日期',
align: 'center',
}, {
field: 'a_id',
title: '作者',
align: 'center',
}, {
field: 'b_intro',
title: '书籍简介',
align: 'center',
}, {
field: 'b_img',
title: '封面',
align: 'center',
}, {
field: 'b_score',
title: '评分',
align: 'center',
}, {
field: 'b_category',
title: '分类',
align: 'center',
}, {
field: 'b_title',
title: '标题',
align: 'center',
}, {
field: 'op',
title: ' *** 作',
align: 'center',
formatter: function (value, row, index) {
var result = "";
result += '';
result += '';
result += '';
result += '';
result += '';
result += '';
return result;
}
}
],
});
}
function search(){
$('#table').bootstrapTable('destroy');
load('/query/');
}
function reset(){
$('#table').bootstrapTable('destroy');
$("#select").val("");
$("#input").val("");
load('/info/');
}
script>
初始化时请求路由‘/info/’会查询整张表,当点击查询按钮查询数据时,需要先将表中内容清空$('#table').bootstrapTable('destroy');
,然后请求查询数据路由,根据返回的数据重新渲染表格;
首先在settings中配置数据库,本文采用的是MySQL数据库,默认使用的是sqlite3
NAME为数据库名称、USER用户名、PASSWORD密码、HOST数据库服务器地址、PORT端口号
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'XXX',
'USER':'XXX',
'PASSWORD':'XXX',
'HOST':'XX.XX.XX.XX',
'PORT':'3306',
}
}
ORM表格创建
此处等待更新
ORM查询 *** 作(1)使用filter过滤器
ob = models.Book.object.filter()
返回的是Query set,可以返回多条结果;验证某个数据是否存在时,可以用ob.count()方法计算结果的数量
(2)get方法
ob = models.Book.object.get()
返回的是Model,可以使用model_to_dict转化为字典进行访问,但是只能返回一个数据,如果有多条数据会报错;判断数据是否存在时,则是判断ob是否为空.
filter适合批量查询,比如查询某个作者写的所有的书籍,适合用filter。
python反射机制根据传递的表名灵活查询
反射机制:通过字符串的形式导入模块;通过字符串的形式,在模块寻找指定函数;通过字符串的形式查找某个函数中的成员
在后端管理系统中,往往有很多信息需要管理,如作者信息和书籍信息,都需要进行全表查询,将查询结果显示在前端界面。所以可以写一个视图函数,来处理全表查询 *** 作,增强代码的复用性,减少冗余性,这就需要指定表名。
在bootstrap-table里queryParams: function (params)函数中,添加参数table_name指定表名。
queryParams: function (params) {//自定义参数,这里的参数是传给后台的
var data = {
size: params.limit, //页面大小
current: (params.offset / params.limit) + 1, //页码
content:$('#input').val(),
condition:$('#select').val(),
table_name:'Book',
};
return data;
},
responseHandler: function (res) {
return res;
},
第一种反射机制:获取模块中的方法
请求方法是POST方法,参数存储在body中,先取出参数,通过getattr()获取models中的方法,第一个反射机制体现在table = getattr(models, body[‘table_name’])中。
最常用方法是models.Book.objects.all(),Book为表名,因此我们通过getattr函数,就可以获取一个table对象,直接使用table.objects.all()即可获取表的全部信息。
if request.method == 'POST':
body = json.loads(request.body)
table = getattr(models, body['table_name'])
size, current = body['size'], body['current']
total = table.objects.count()
infos = table.objects.all().order_by()
#Paginator用于后端分页
paginator = Paginator(infos, per_page=size)
page_object = paginator.page(current)
total = infos.count()
rows = []
for item in page_object:
d = model_to_dict(item)
for k, v in d.items():
if 'date' in k:
d[k] = str(v)
elif k == "a_id":
d[k] = item.a_id.a_name
rows.append(d)
data = {'total': total, 'rows': rows}
return HttpResponse(json.dumps(data), content_type='application/json')
注意:bootstrap-table接收的数据类型必须为{'total':total.'rows':rows}
,因此需要先将数据转换成该形式,再返回给前端。此外,返回的数据必须是字符串类型,才可以显示在表格中,如果含有date类型数据,需要现将其转换为字符串。
第二种反射机制:获取某个成员中的元素
主要是先获取表格中的所有字段,再根据字段信息获取该字段对应的value值,其实本质想将model或者queryset数据转换为bootstrap可以接受的形式。但是后面发现可以直接使用model_to_dict实现,所以就舍弃了下面的方法;这种思路可以借鉴。
body = json.loads(request.body)
table = getattr(models, body['table_name'])
fields = table._meta.fields
infos = table.objects.all()
d = {}
rows = []
for info in infos:
for f in fields:
d[f] = getattr(info,f)
rows.append(d)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)