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服务 ...
随机推荐
- html学习笔记-XML-Javascript
html学习笔记-XML-Javascript Table of Contents 1. XML HTTP Request 1.1. XMLHttpRequest 对象 1.2. 创建 XMLHttp ...
- Java中的多线程详解
如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个话其 ...
- [PCL]对‘pcl::visualization::CloudViewer::CloudViewer(std::string const&)’未定义的引用
pcl::visualization::CloudViewer viewer("Cloud Viewer"); 这个时候报错. 试了很多方法,有人说,targe t_link 时候 ...
- datatables添加长按事件
长按事件 $.fn.longPress = function (fn) { var timeout = undefined; var $this = this; for (var i = 0; i & ...
- 洛谷 P3353 在你窗外闪耀的星星
题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的 ...
- 最全面的 python 字符串拼接总结(带注释版)
在 Python 中字符串连接有多种方式,这里简单做个总结,应该是比较全面的了,方便以后查阅. 加号连接 第一种,通过+号的形式: >>> a, b = 'hello', ' wor ...
- appium---启动app
自动化测试是测试人员必备的一项技能,所谓的自动化就是通过代码完成了手工的操作,今天就总结下如何通过python启动app 环境条件 1.安装python:下载地址 2.安装JDK:下载地址 3.安装A ...
- python 列表 字典转json
一.Dictionary 转为JSON 将dict转为JSON,这里利用包json import jsonaItem = {}aItem["id"] = "2203&qu ...
- SC || Git 相关知识
发现大佬的博客:https://www.cnblogs.com/onetwo/p/4157610.html 注:图片来自小姐姐的笔记~ ┉┉┉∞ ∞┉┉┉┉∞ ∞┉┉┉∞ ∞┉┉┉┉┉∞ ∞┉┉┉┉∞ ...
- JQuery EasyUI学习记录(三)
1.jQuery EasyUI messager使用方式 1.1 alert方法 $(function(){ //1.alert方法---提示框 $.messager.alert("标题&q ...