Python 实战一
列表ID的显示
起初ID显示的是数据库中的id,因为数据库中的id是自增长的,所以删除一条后,这里显示就叉开了,这里使用索引的方式来显示。
这个功能实现的逻辑:
第一:定义一个表格的架构,用id=‘idc-list’来获取表格tbody的内容
<table id='my-idc-table' class='table table-bordered'>
<thead>
<tr>
<th>ID</th>
<th>机房</th>
<th>手机</th>
<th>操作</th>
</tr>
</thead>
<tbody id="idc-list"></tbody> </table>
第二步:使用jquery来获取tbody的数据。利用each循环来排列后端返回给的数据
function getList(){
$.getJSON('/listapi?table_name=idc',function(res){
var html_str = ''
$.each(res,function(i,j){
html_str += '<tr>'
html_str += '<td>'+j[3]+'</td>'
html_str += '<td>'+j[1]+'</td>'
html_str += '<td>'+j[2]+'</td>'
html_str += '<td><button class="del-btn btn btn-danger btn-xs" data-name="'+j[1]+'" data-id="'+j[0]+'">delete</button></td>'
html_str += '</tr>'
})
//console.log([$('#idc-list').html()]) render_table('my-idc-table',html_str) })
} getList()
这里使用到了定义到laylou2.html中的render_table函数
function render_table(table_id,html_str){
var $table = $('#'+table_id) var $tbody = $table.find('tbody') if($tbody.html()){
$table.DataTable().destroy() #销毁实例,这个DataTable是用的第三方插件,来显示table的
}
$tbody.html(html_str)
$table.DataTable({ bLengthChange:false #开关,是否显示一个每页长度的选择条(须要分页器支撑)
});
}
第三步:在后端把数据传递给前端之前,就可以吧索引加上。
后端通过在数据库中select * form 表名; 获取到的数据是个元组,格式如下:
((12L, u'\u5929\u6d25', u'1810'), (13L, u'\u6cb3\u5317', u'188'), (14L, u'\u5317\u4eac', u'1999'), (15L, u'\u5317\u4eac', u'199'), (16L, u'\u53f0\u6e7e', u'111'), (20L, u'\u6d77\u5357', u'1234'))
然后在后端把索引加入。
def listapi():
rev_table_name = request.args.get('table_name')
result = db.list(rev_table_name)
new_result = []
for i in range(len(result)):
new_result.append(list(result[i]) + [i+1]) #利用数组相加的方法给添加上索引
print new_result
return json.dumps(new_result)
方法二:利用列表生成式来简写 [list(a[i])+[i+1] for i in range(len(a))] ,原理一样
方法三:如何用map实现?
增加用户的实现
前端代码:
<button id='add-idc' data-toggle="modal" data-target="#add-idc-modal" class='btn btn-primary'>新增机房</button> <table id='my-idc-table' class='table table-bordered'>
<thead>
<tr>
<th>ID</th>
<th>机房</th>
<th>手机</th>
<th>操作</th>
</tr>
</thead>
<tbody id="idc-list"></tbody> </table>
<!-- Modal -->
<div class="modal fade" id="add-idc-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog modal-sm" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">新建机房</h4>
</div>
<div class="modal-body"> <form class="form-horizontal" id='add-form'>
<input type='hidden' name="table_name" value='idc'>
<div class="form-group">
<label class="col-sm-4 control-label">机房名</label>
<div class="col-sm-8">
<input type="text" name='name' class="form-control" >
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">电话</label>
<div class="col-sm-8">
<input type="text" name='mobile' class="form-control" >
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" id='add-confirm' class="btn btn-primary">新增</button>
</div>
</div>
</div>
</div>
add user
模态窗跳转是通过,data-target="#add-idc-modal"来控制的。
然后jquer通过"add-confirm"来确认提交的信息,然后通过ajax传递给后端增加的信息。
$('#add-confirm').click(function(){
var o=$('#add-form').serialize()
$.post('/addapi',o,function(res){
res = JSON.parse(res)
console.log(res.code)
if(res.code==0){
getList()
$('#add-idc-modal').modal('hide')
$('#add-form')[0].reset()
swal('添加成功','','success')
}else{
swal(res.msg,'','error')
}
})
})
serialize 序列化功能,form表单中提交的信息都可以给序列化出来
这里传递给后端的table_name是通过隐藏的input来实现的。
flask代码:
@app.route('/addapi', methods=['POST'])
def addapi():
rev_dict = request.form.to_dict() #转换为字典
rev_tab_name = rev_dict.pop('table_name')
result = db.add(rev_tab_name,rev_dict)
return json.dumps(result) @app.route('/listapi')
mysql代码:
def add(self,table_name,table_val): #table_val格式 : {name=xxx,mobile=wwww}
table_key = ','.join(table_val.keys())
key_val = ','.join(["'%s'"%v for v in table_val.values()])
# sql = "insert into %s (%s) values (%s)"%(table_name,col_names,values)
sql = "insert into %s (%s) values (%s)"%(table_name,table_key,key_val)
self.execute(sql)
return {'code':0}
删除某个条目
删除的条目想起初想的是利用username来删除,结果没有实现,结果用id来删除比较方便。
这里之前用过模板继承,可否来记得,定义一个大的模板layout2.html,layout2.html中定义了大的框架块。然后其他的小选项中可以来引用这个大的块,然后还可以在添加自己的内容,这里html的代码能模块话,当然页面中相同的利用jquey操作也可以模块化,定义到layout2.html中,下面就利用模块化来删除某个条目。
layout2.html 中代码
function bind_delete(selector,table_name){
$(document).on('click',selector,function(){
var id = $(this).attr('data-id') #获取id的值 swal({
title: "confirm",
text: "确认删除"+$(this).attr('data-name')+"?",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "yes",
closeOnConfirm: false
},
function(){
$.post('/deleteapi',{id:id,table_name:table_name},function(res){
if(res=='ok'){ swal('success','','success')
getList()
}else{
swal('error','删除失败','error')
}
})
});
}) }
idc.html 中的代码:
bind_delete('.del-btn','idc') #直接就一行调用函数的代码,传入需要操作的对象及表名字。
flask 代码:
def deleteapi():
table_name = request.form.get('table_name')
row_id = request.form.get('id')
print '=='*40
print row_id
result = db.remove(table_name,row_id)
return 'ok'
mysql 代码:
def remove(self,table_name,row_id):
sql = 'delete from %s where id=%s'%(table_name,row_id)
print '++++'*30
print sql
res = self.execute(sql)
print res
return res
期间遇到一个数据库报错的问题
def execute(self,sql):
# error handle
try:
print self.cursor.execute(sql)
return self.cursor
except mysql.OperationalError as e:
# connect
print e
print 'reconnect db'
self.connect()
time.sleep(1)
return self.execute(sql)
执行的时候一直输出, reconnect db.....
排查的方法是mysql的报错打印出来, as e: 再print e.
实现左侧图标点击高亮
前端代码:
<ul id='navsidebar' class="nav nav-sidebar">
<li ><a href="/user">用户名</a></li>
<li><a href="/idc">机房</a></li>
<li><a href="/pc">机器</a></li> var path = location.pathname
var $page = $('#navsidebar').find('[href="'+path+'"]')
$page.parent().addClass('active') $('#page-header-title').html($page.html())
思路:通过location.pathname,获取当前在哪个目录下,然后通过find,找到这个元素,在对其父层做active处理,便实现了这个效果
小知识点
<script>
$(document).ready(function () {
$('#test').html('hello python')
}) $(function () {
$('#test').html("hello python ")
}) </script>
这两种写法是相同的,第二种是第一种的简写。
下拉框的实现
机房>>>新增机器>>>IDC 下拉框的实现
可以通过下拉框来选择机房。
<div class="form-group">
<label class="col-sm-2 control-label">IDC</label>
<div class="col-sm-8">
<select name='idc' class="form-control" id = 'add-idc-select'>
</select>
</div>
</div>
通过jquery & ajax去调用数据库的数据库返回。
function getidc(){
$.getJSON('/listapi?table_name=idc',function(res){
var option_str = ''
$.each(res,function(i,v){
option_str += '<option value='+v[0]+'>'+v[1]+'</option>'
})
$('#add-idc-select').html(option_str)
})
} getidc()
时间选择器
基于的css/js
href="/static/bootstrap-datetimepicker.css"
src='/static/bootstrap-datetimepicker.js'
这两个是基于jquery的,得写到jquery的下面。
代码:
$('#add-pc-time,#update-pc-time').datetimepicker({
startView: 2,
minView: 2,
format:"yyyy-mm-dd"
})
update后端数据在前端展示
实现的功能,点击update后会把后端的数据展示的表里面,修改后,点击更新会提交到后端。
第一步:
首先要把后端的内容在前端展示,设计的思路是吧需要展示的内容都绑定到update键上面。然后再利用each循环,展示到table当中
update button需要绑定的内容:
function getList(){
$.getJSON('/listapi?table_name=pc',function(res){
var html_str = ''
$.each(res,function(i,j){
html_str += '<tr>'
html_str += '<td>'+j[7]+'</td>'
html_str += '<td>'+j[1]+'</td>'
html_str += '<td>'+j[2]+'</td>'
html_str += '<td>'+j[3]+'</td>'
html_str += '<td>'+j[4]+'</td>'
html_str += '<td>'+j[5]+'</td>'
html_str += '<td>'+j[6]+'</td>'
html_str += '<td>'
html_str += '<button class="del-btn btn btn-danger btn-xs" data-name="'+j[1]+'" data-id="'+j[0]+'">delete</button>'
html_str += '<button class="update-btn btn btn-success btn-xs" data-id="'+j[0]+'" data-ip="'+j[1]+'" data-memory="'+j[2]+'" data-disk="'+j[3]+'" data-idc="'+j[4]+'" data-buy_time="'+j[5]+'" data-comment="'+j[6]+'" >update</button>'
html_str += '</td>'
html_str += '</tr>'
})
//console.log([$('#pc-list').html()]) render_table('my-pc-table',html_str) })
}
点击update后内容的回调:
$(document).on('click','.update-btn',function(){
$('#update-pc-modal').modal('show') //跳出模态框
// console.log($(this).data()) //定义的都是data-XX开头,所以通过$(this).date()就可以获取这些关键字
$.each($(this).data(),function(i,v){
//console.log(i,'----->',v)
$('#update-pc-form').find('[name='+i+']').val(v) //通过name选择器来选择,然后做显示。 })
})
下一步就是更新后的内容返回给后端了:
update的代码与add相似,就是把数据序列化后传递给后端:
$('#update-pc-btn').click(function(){
var o=$('#update-pc-form').serialize()
alert(o)
$.post('/updateapi',o,function(res){
res = JSON.parse(res)
console.log(res)
console.log(res.code)
if(res.code==0){
getList()
$('#update-pc-modal').modal('hide')
swal('更新成功','','success')
}else{
swal(res.msg,'','error')
}
})
})
然后flask接受传递来的数据,
def updateapi():
allval = request.form.to_dict()
print '%%'*40
table_name = allval.pop('table_name')
print table_name
print allval
res = db.update(table_name,allval)
if res == 'ok':
return '{"code":0}'
else:
return '{"code":1}'
执行数据库:
def update(self,table_name,args):
arg_id = args.pop('id')
temp = ['%s="%s"'%item for item in args.items()] //循环的item是个元组的形式
update_str = ','.join(temp)
sql = 'update %s set %s where id=%s'%(table_name,update_str,arg_id)
db.execute(sql)
return 'ok'
用户登录基础的session实现
#coding=utf-8
from flask import Flask,render_template,request,redirect,session
from dbutil import db
import json
#from dbutil import db app = Flask(__name__)
app.secret_key='' @app.route('/')
def index():
#res = db.list('users')
#return json.dumps(res)
return redirect('/idc') @app.route('/login', methods=['POST','GET'])
def login():
if request.method == "GET":
if 'username' in session: #判断session是否已经存在了
return redirect('/idc')
else:
return render_template('login.html')
if request.method == "POST":
username = request.form.get('username')
password = request.form.get('password')
res = db.list('user',where={'username':username,'password':password})
print 'res===>',res
if len(res) == 0:
return 'login error'
else:
session['username'] = username #增加到session里面
return redirect('/idc') @app.route('/logout')
def logout():
del session['username'] #退出删除session
return redirect('/login')
flask Code
def list(self,table_name,col_name='*',where={}):
#select * from user where username='admin' and password='admin'; 判断用户是否存在
sql = 'select %s from %s'%(col_name,table_name)
print 'where',where
if where:
temp = ' where '
temp += 'and'.join([' %s="%s" '%item for item in where.items()])
sql += temp
print 'sql',sql
print sql
res = self.execute(sql)
return res.fetchall() ##数据库中查找用户是否存在!!
flask login_required 用法:
定义一个方法:
def login_required(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if not session.get('username'):
return redirect('/login')
return f(*args, **kwargs)
return decorated_function
然后每个url都去@调用这个方法就实现了seesion的引用
@app.route('/secret_page')
@login_required
def secret_page():
pass
另外还可以定义一次,在请求调用这个,不必每个页面都去调用了,@app.before_request,后面做详细学习。
token的使用
token 主要用于调用api接口时候的验证。
基本的原理如同下面的小例子:
首先我们需要基于一种加密算法,如 base64 ,可正反互解的。然后根据根据客户传递过来的信息,如用户名、密码、role,再加上过期时间做加密,然后把这串字符作为token传给客户,下次访问的时候url中带上token,服务器端做解密,然后核对用户信息,时间是否过期等,如果正常则返回给客户所需要的信息。
#!/usr/bin/python
#coding: utf-8 import base64
import time secret_key = 'woqunianmailegebiao' def create_token(user,role): #加密过程
temp = '%s|%s|%s|%s'%(secret_key,user,role,int(time.time()+60*60*12))
return base64.b64encode(temp) #print create_token('reboot','admin')
def verify_token(token): #解密验证过程
temp = base64.b64decode(token).split('|')
if len(temp) ==4:
secret,user,role,expire_time = temp
if secret == secret_key:
if int(expire_time) > time.time():
return {'code':0,'user':user,'role':role}
else:
return {'code':20,'msg':'expire time !!'}
else:
return {'code':10,'mes':"wrong key"}
else:
return {'code':1,'msg':'wrong token'} #print verify_token('d29xdW5pYW5tYWlsZWdlYmlhb3xyZWJvb3R8YWRtaW58MTUwMTYyNDYwMQ==')
如果通过登录的方式,就把token传递给前端了,前端可以使用自己生成url的方法来使请求的url带上token的字段
首先定义一个myget的方法,来对$.get请求的内容做填丛
//定义api请求的方法
$.myget = function(url,data,fn){
if(localStorage.token){
$.get(url+'?access_token'+localStorage.token,data,fn)
}else{
location.href='/login'
}
}
然后在请求listapi时,代替传统的$.api
function getList(){ $.myget('/listapi','table_name=idc',function(res){
var res = JSON.parse(res)
//$.getJSON('/listapi?table_name=idc',function(res){
var html_str = ''
$.each(res,function(i,j){
html_str += '<tr>'
html_str += '<td>'+j[3]+'</td>'
html_str += '<td>'+j[1]+'</td>'
html_str += '<td>'+j[2]+'</td>'
html_str += '<td><button class="del-btn btn btn-danger btn-xs" data-name="'+j[1]+'" data-id="'+j[0]+'">delete</button></t
d>'
html_str += '</tr>'
})
//console.log([$('#idc-list').html()]) render_table('my-idc-table',html_str) })
} getList()
绘图展示
获取内存信息的土著方法:
import time def get_mem():
with open('/proc/meminfo') as f:
total = f.readline().split()[1]
free = f.readline().split()[1]
ava = f.readline().split()[1]
buf = f.readline().split()[1]
cache = f.readline().split()[1]
print ('free %s ava %s')%(free,ava) while True:
get_mem()
time.sleep(2) 利用psutil的升华版 #!/usr/bin/python
# coding: utf-8 import psutil as ps
import time def get_mem():
mem_info = ps.virtual_memory().available
print mem_info while True:
get_mem()
time.sleep(2)
psutil 模块
Python 实战一的更多相关文章
- Python实战一
要求:用户输入用户名和密码错误三次,就对该用户进行锁定,不让其进行登录. def match(name,pwd): '''匹配用户输入的信息,进行判断''' falg = True while fal ...
- 机器学习实战一:kNN手写识别系统
实战一:kNN手写识别系统 本文将一步步地构造使用K-近邻分类器的手写识别系统.由于能力有限,这里构造的系统只能识别0-9.需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:32像素*3 ...
- 【转】Delphi+Halcon实战一:两行代码识别QR二维码
Delphi+Halcon实战一:两行代码识别QR二维码 感谢网友:绝代双椒( QQ号应原作者要求隐藏了:xxxx6348)的支持 本文是绝代双椒的作品,因为最近在忙zw量化培训,和ziwang.co ...
- C蛮的全栈之路-node篇(二) 实战一:自动发博客
目录 C蛮的全栈之路-序章 技术栈选择与全栈工程师C蛮的全栈之路-node篇(一) 环境布置C蛮的全栈之路-node篇(二) 实战一:自动发博客 ---------------- 我是分割线 ---- ...
- 【实战】Docker 入门实战一:ubuntu 和 centos 安装Docker
Docker是什么 Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源.Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布 ...
- zookeeper curator ( 实战一)
目录 zookeeper 的伪集群搭建 写在前面 1.1. zookeeper 安装&配置 1.1.1. 创建数据目录和日志目录: 1.1.2. 创建myid文件 1.1.3. 创建和修改配置 ...
- Netty聊天器(实战一):从0开始实战100w级流量应用
Java 聊天程序(百万级流量实战一):系统介绍 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之14 [博客园 总入口 ] 源码IDEA工程获取链接:Java 聊天室 实战 源码 写在前面 ...
- 【k8s实战一】Jenkins 部署应用到 Kubernetes
[k8s实战一]Jenkins 部署应用到 Kubernetes 01 本文主旨 目标是演示整个Jenkins从源码构建镜像到部署镜像到Kubernetes集群过程. 为了简化流程与容易重现文中效果, ...
- miniFTP项目实战一
项目简介: 在Linux环境下用C语言开发的Vsftpd的简化版本,拥有部分Vsftpd功能和相同的FTP协议,系统的主要架构采用多进程模型,每当有一个新的客户连接到达,主进程就会派生出一个ftp服务 ...
随机推荐
- go日志输入到es
1.依赖 github.com/alecthomas/log4go 2.配置 <filter enabled="true"><!-- enabled=false ...
- feign容断忽略某些异常
@HystrixCommand(ignoreExceptions={ BusinessException.class, IllegalArgumentException.class, BadCrede ...
- canvas雪花特效-jQuery插件实现
这是一款效果十分逼真的html5 canvas下雪场景动画特效插件.这款下雪特效是基于Jason Brown的Snowfall jquery plugin的基础上制作的.在Snowfall jquer ...
- Ubuntu 12.04源
deb http://ubuntu.uestc.edu.cn/ubuntu/ precise main restricted universe multiverse deb http://ubuntu ...
- CoordinatorLayout使用笔记
CoordinatorLayout的使用笔记 首先第一个子控件是AppBarLayout存放首部控件,里面放了一个CollapsingToolbarLayout.代码如下: <android.s ...
- JavaScript模板引擎的使用
为了将数据库中的一组记录转换成HTML输出到界面上,大家都采用哪些做法呢? 在WebForm时代我们经常使用datagrid.repeater,当MVC问世后我们开始直接在视图上编写C#循环语句,而现 ...
- sessionStorage 详解,特点,使用技巧,场景
很早之前久知道sessionStorage ,也学习过,但没有实战使用过 .最近团队遇到一个问题<electronjs中打开新页面sessionStorage丢失>,让我有机会重新来认识一 ...
- python基础教程总结14——测试
1. 先测试,后编码 对程序的各个部分建立测试也是非常重要的(这也称为单元测试).测试驱动编程:Test-driven programming 1)精确的需求说明: 程序设计的理念是以编写测试程序开始 ...
- codeforce Gym 100500E IBM Chill Zone (SG函数)
关于sg函数这篇blog讲得很详细http://blog.csdn.net/logic_nut/article/details/4711489. sg函数的价值在于把复杂的游戏拆分成简单的游戏,然后通 ...
- vue中的修饰符
Vue2.0学习笔记:Vue事件修饰符的使用 事件处理 如果需要在内联语句处理器中访问原生DOM事件.可以使用特殊变量$event,把它传入到methods中的方法中. 在Vue中,事件修饰符处理 ...