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服务 ...
随机推荐
- CSS中垂直水平居中
方法一:使用flex布局,父级元素设置justify-content和align-items <div class="cont"> <div class=&quo ...
- Java_面向对象的 static 和 abstract
static:表示静态的 static:可以用来修饰属性.方法.代码块(或初始化块).内部类. 一.static修饰属性(类变量): public class TestStatic { //stati ...
- jdk动态代理和cglib动态代理的区别
一.原理区别: java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. 而cglib动态代理是利用asm开源包,对代理对象类的class文件 ...
- (二)我的JavaScript系列:JavaScript面向对象旅程(下)
剪不断,理还乱,是离愁. 前面已经提到过新语言开发的两个步骤,分别是:一.定义基本的数据类型,完善结构化编程语言的设计:二.为函数类型绑定this的概念,好在对象的方法中可以引用到对象自身.下面是继续 ...
- SqlServer中提示和报错信息的翻译
有时候遇到SqlServer一些报错需要上网查找解决方法,一些比较生僻的问题汉语搜索往往得不到想要的,就要使用英文在外网搜索.之前都是自己尝试翻译,或者使用错误码,或者找个英文版的数据库重现问题.有时 ...
- 编写C#程序,自动将bing首页图片设为壁纸
任务目标: 1,获取图片 2,设为壁纸 3,自动化 环境需求: .NET Framework 4.0+, Visual Studio 2017 ==================== 1,获取图片 ...
- Python-OpenCV——亮度和对比度
亮度与对比度 亮度调整是将图像像素的强度整体变大/变小,对比度调整指的是图像暗处变得更暗,亮出变得更亮,从而拓宽某个区域内的显示精度. OpenCV中亮度和对比度应用这个公式来计算:g(x) = αf ...
- Memcache使用基础
Memcached的特点: 协议简单 基于libevent的事件处理 内置内存存储方式 memcached不互相通信的分布式 1.协议简单: 使用简单的基于 ...
- 从输入url到页面加载完成发生了什么详解
这是一道经典的面试题,这道题没有一个标准的答案,它涉及很多的知识点,面试官会通过这道题了解你对哪一方面的知识比较擅长,然后继续追问看看你的掌握程度.当然我写的这些也只是我的一些简单的理解,从前端的角度 ...
- Bootstrap历练实例:语境色彩的面板
带语境色彩的面板 使用语境状态类 panel-primary.panel-success.panel-info.panel-warning.panel-danger,来设置带语境色彩的面板,实例如下: ...