Python 实战一

列表ID的显示

  起初ID显示的是数据库中的id,因为数据库中的id是自增长的,所以删除一条后,这里显示就叉开了,这里使用索引的方式来显示。

  这个功能实现的逻辑:

  第一:定义一个表格的架构,用id=‘idc-list’来获取表格tbody的内容

 1 <table id='my-idc-table' class='table table-bordered'>
 2     <thead>
 3         <tr>
 4             <th>ID</th>
 5             <th>机房</th>
 6             <th>手机</th>
 7             <th>操作</th>
 8         </tr>
 9     </thead>
10     <tbody id="idc-list"></tbody>
11 
12 </table>  

  第二步:使用jquery来获取tbody的数据。利用each循环来排列后端返回给的数据

 1    function getList(){
 2        $.getJSON('/listapi?table_name=idc',function(res){
 3           var html_str = ''
 4           $.each(res,function(i,j){
 5             html_str += '<tr>'
 6             html_str += '<td>'+j[3]+'</td>'
 7             html_str += '<td>'+j[1]+'</td>'
 8             html_str += '<td>'+j[2]+'</td>'
 9             html_str += '<td><button class="del-btn btn btn-danger btn-xs" data-name="'+j[1]+'" data-id="'+j[0]+'">delete</button></td>'
10             html_str += '</tr>'
11           })
12        //console.log([$('#idc-list').html()])
13 
14        render_table('my-idc-table',html_str)
15 
16        })
17    }
18 
19 getList()

  这里使用到了定义到laylou2.html中的render_table函数

 

 1 function render_table(table_id,html_str){
 2         var $table = $('#'+table_id)
 3 
 4         var $tbody = $table.find('tbody')
 5 
 6          if($tbody.html()){
 7              $table.DataTable().destroy()   #销毁实例,这个DataTable是用的第三方插件,来显示table的
 8          }
 9          $tbody.html(html_str)
10          $table.DataTable({
11          
12              bLengthChange:false      #开关,是否显示一个每页长度的选择条(须要分页器支撑)
13          });
14 }

 

 

  第三步:在后端把数据传递给前端之前,就可以吧索引加上。

  后端通过在数据库中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'))

   然后在后端把索引加入。

1 def listapi():
2     rev_table_name = request.args.get('table_name')
3     result = db.list(rev_table_name)
4     new_result = []
5     for i in range(len(result)):
6         new_result.append(list(result[i]) + [i+1])      #利用数组相加的方法给添加上索引
7     print new_result
8     return json.dumps(new_result)

  方法二:利用列表生成式来简写   [list(a[i])+[i+1] for i in range(len(a))]  ,原理一样

  方法三:如何用map实现?

 

增加用户的实现

前端代码:

 1 <button id='add-idc' data-toggle="modal" data-target="#add-idc-modal"  class='btn btn-primary'>新增机房</button>
 2 
 3 <table id='my-idc-table' class='table table-bordered'>
 4     <thead>
 5         <tr>
 6             <th>ID</th>
 7             <th>机房</th>
 8             <th>手机</th>
 9             <th>操作</th>
10         </tr>
11     </thead>
12     <tbody id="idc-list"></tbody>
13 
14 </table>
15 <!-- Modal -->
16 <div class="modal fade" id="add-idc-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
17   <div class="modal-dialog modal-sm" role="document">
18     <div class="modal-content">
19       <div class="modal-header">
20         <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
21         <h4 class="modal-title" id="myModalLabel">新建机房</h4>
22       </div>
23       <div class="modal-body">
24 
25 <form class="form-horizontal" id='add-form'>
26     <input type='hidden' name="table_name" value='idc'>
27   <div class="form-group">
28     <label class="col-sm-4 control-label">机房名</label>
29     <div class="col-sm-8">
30       <input type="text" name='name' class="form-control"  >
31     </div>
32   </div>
33   <div class="form-group">
34     <label  class="col-sm-4 control-label">电话</label>
35     <div class="col-sm-8">
36       <input type="text" name='mobile' class="form-control" >
37     </div>
38   </div>
39 </form>
40       </div>
41       <div class="modal-footer">
42         <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
43         <button type="button" id='add-confirm' class="btn btn-primary">新增</button>
44       </div>
45     </div>
46   </div>
47 </div>
add user

  模态窗跳转是通过,data-target="#add-idc-modal"来控制的。

   然后jquer通过"add-confirm"来确认提交的信息,然后通过ajax传递给后端增加的信息。

 1    $('#add-confirm').click(function(){
 2        var o=$('#add-form').serialize()
 3        $.post('/addapi',o,function(res){
 4            res = JSON.parse(res)
 5            console.log(res.code)
 6            if(res.code==0){
 7               getList()
 8               $('#add-idc-modal').modal('hide')    
 9               $('#add-form')[0].reset()
10               swal('添加成功','','success')
11            }else{
12               swal(res.msg,'','error')
13            }
14        })
15    })

  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代码:

1     def add(self,table_name,table_val):       #table_val格式 : {name=xxx,mobile=wwww}
2         table_key = ','.join(table_val.keys())              
3         key_val = ','.join(["'%s'"%v for v in table_val.values()]) 
4        # sql = "insert into %s (%s) values (%s)"%(table_name,col_names,values)
5         sql = "insert into %s (%s) values (%s)"%(table_name,table_key,key_val)
6         self.execute(sql)
7         return {'code':0}

 

删除某个条目

   删除的条目想起初想的是利用username来删除,结果没有实现,结果用id来删除比较方便。

  这里之前用过模板继承,可否来记得,定义一个大的模板layout2.html,layout2.html中定义了大的框架块。然后其他的小选项中可以来引用这个大的块,然后还可以在添加自己的内容,这里html的代码能模块话,当然页面中相同的利用jquey操作也可以模块化,定义到layout2.html中,下面就利用模块化来删除某个条目。

layout2.html 中代码

 1 function bind_delete(selector,table_name){
 2 $(document).on('click',selector,function(){
 3     var id = $(this).attr('data-id')              #获取id的值
 4 
 5     swal({
 6       title: "confirm",
 7       text: "确认删除"+$(this).attr('data-name')+"?",
 8       type: "warning",
 9       showCancelButton: true,
10       confirmButtonColor: "#DD6B55",
11       confirmButtonText: "yes",
12       closeOnConfirm: false
13     },
14     function(){
15         $.post('/deleteapi',{id:id,table_name:table_name},function(res){
16             if(res=='ok'){
17 
18                 swal('success','','success')   
19                 getList()
20             }else{
21                 swal('error','删除失败','error')
22             }
23         })
24     });
25 })
26 
27 }

idc.html 中的代码:

  bind_delete('.del-btn','idc')    #直接就一行调用函数的代码,传入需要操作的对象及表名字。

flask 代码:

1 def deleteapi():
2     table_name = request.form.get('table_name')
3     row_id = request.form.get('id')
4     print '=='*40
5     print row_id
6     result = db.remove(table_name,row_id)
7     return 'ok'

mysql 代码:

1     def remove(self,table_name,row_id):
2         sql = 'delete from %s where id=%s'%(table_name,row_id)
3         print '++++'*30
4         print sql
5         res = self.execute(sql)
6         print res 
7         return res

 期间遇到一个数据库报错的问题

 1     def execute(self,sql):
 2         # error handle
 3         try: 
 4             print self.cursor.execute(sql)    
 5             return self.cursor
 6         except mysql.OperationalError as e:
 7             # connect
 8             print e 
 9             print 'reconnect db'
10             self.connect()
11             time.sleep(1)
12             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处理,便实现了这个效果

 

小知识点 

 1   <script>
 2         $(document).ready(function () {
 3             $('#test').html('hello python')
 4         })
 5         
 6         $(function () {
 7             $('#test').html("hello python ")
 8         })
 9         
10   </script>

  这两种写法是相同的,第二种是第一种的简写。

 

下拉框的实现

   机房>>>新增机器>>>IDC 下拉框的实现

  

  可以通过下拉框来选择机房。

1     <div class="form-group">
2     <label class="col-sm-2 control-label">IDC</label>
3     <div class="col-sm-8">
4         <select name='idc' class="form-control" id = 'add-idc-select'>
5         </select>
6     </div>
7   </div>

  通过jquery & ajax去调用数据库的数据库返回。

 1 function getidc(){
 2     $.getJSON('/listapi?table_name=idc',function(res){
 3         var option_str = ''
 4         $.each(res,function(i,v){
 5             option_str += '<option value='+v[0]+'>'+v[1]+'</option>'
 6         })
 7         $('#add-idc-select').html(option_str)
 8     })
 9 }
10 
11 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需要绑定的内容:

 1    function getList(){
 2        $.getJSON('/listapi?table_name=pc',function(res){
 3           var html_str = ''
 4           $.each(res,function(i,j){
 5             html_str += '<tr>'
 6             html_str += '<td>'+j[7]+'</td>'
 7             html_str += '<td>'+j[1]+'</td>'
 8             html_str += '<td>'+j[2]+'</td>'
 9             html_str += '<td>'+j[3]+'</td>'
10             html_str += '<td>'+j[4]+'</td>'
11             html_str += '<td>'+j[5]+'</td>'
12             html_str += '<td>'+j[6]+'</td>'
13             html_str += '<td>'
14             html_str += '<button class="del-btn btn btn-danger btn-xs" data-name="'+j[1]+'" data-id="'+j[0]+'">delete</button>'
15             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>'
16             html_str += '</td>'
17             html_str += '</tr>'
18           })
19        //console.log([$('#pc-list').html()])
20 
21        render_table('my-pc-table',html_str)
22 
23        })
24    }

点击update后内容的回调:

1 $(document).on('click','.update-btn',function(){
2     $('#update-pc-modal').modal('show')         //跳出模态框
3        // console.log($(this).data())       //定义的都是data-XX开头,所以通过$(this).date()就可以获取这些关键字
4        $.each($(this).data(),function(i,v){
5          //console.log(i,'----->',v)
6          $('#update-pc-form').find('[name='+i+']').val(v)    //通过name选择器来选择,然后做显示。
7 
8        })
9 })

 

下一步就是更新后的内容返回给后端了:

  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接受传递来的数据,

 1 def updateapi():
 2     allval = request.form.to_dict()
 3     print '%%'*40
 4     table_name = allval.pop('table_name')
 5     print table_name
 6     print allval
 7     res = db.update(table_name,allval)
 8     if res == 'ok':
 9         return '{"code":0}'
10     else:
11         return '{"code":1}'

执行数据库:

1     def update(self,table_name,args):
2         arg_id = args.pop('id')
3         temp = ['%s="%s"'%item for item in args.items()]        //循环的item是个元组的形式
4         update_str = ','.join(temp)
5         sql = 'update %s set %s where id=%s'%(table_name,update_str,arg_id)
6         db.execute(sql)
7         return 'ok'

 

 用户登录基础的session实现

 1 #coding=utf-8
 2 from flask import  Flask,render_template,request,redirect,session
 3 from dbutil import db
 4 import json
 5 #from dbutil import db
 6 
 7 app = Flask(__name__)
 8 app.secret_key='1234567890'
 9 
10 @app.route('/')
11 def index():
12     #res = db.list('users')
13     #return json.dumps(res)
14     return redirect('/idc')
15 
16 @app.route('/login', methods=['POST','GET'])
17 def login():
18     if request.method == "GET":
19         if 'username' in session:             #判断session是否已经存在了
20             return redirect('/idc')
21         else:
22             return render_template('login.html')
23     if request.method == "POST":
24         username = request.form.get('username')
25         password = request.form.get('password')
26         res = db.list('user',where={'username':username,'password':password})
27         print 'res===>',res
28         if len(res) == 0:
29             return 'login error'
30         else:
31             session['username'] = username         #增加到session里面
32             return redirect('/idc')
33 
34 @app.route('/logout')
35 def logout():
36     del session['username']                     #退出删除session
37     return redirect('/login')
flask Code
 1     def list(self,table_name,col_name='*',where={}):
 2         #select * from user where username='admin' and password='admin'; 判断用户是否存在
 3         sql = 'select %s from %s'%(col_name,table_name)
 4         print 'where',where
 5         if where:
 6             temp = ' where '
 7             temp += 'and'.join([' %s="%s" '%item for item in where.items()])
 8             sql += temp
 9             print 'sql',sql
10         print sql
11         res = self.execute(sql)
12         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,服务器端做解密,然后核对用户信息,时间是否过期等,如果正常则返回给客户所需要的信息。  

 1 #!/usr/bin/python
 2 #coding: utf-8
 3 
 4 import base64
 5 import time
 6 
 7 secret_key = 'woqunianmailegebiao'
 8 
 9 
10 def create_token(user,role):                #加密过程
11     temp = '%s|%s|%s|%s'%(secret_key,user,role,int(time.time()+60*60*12))
12     return base64.b64encode(temp)
13 
14 #print create_token('reboot','admin')
15 def verify_token(token):                    #解密验证过程
16     temp = base64.b64decode(token).split('|')
17     if len(temp) ==4:
18         secret,user,role,expire_time = temp
19         if secret == secret_key:
20             if int(expire_time) > time.time():
21                 return {'code':0,'user':user,'role':role}
22             else:
23                 return {'code':20,'msg':'expire time !!'}
24         else:
25             return {'code':10,'mes':"wrong key"}
26     else:
27         return {'code':1,'msg':'wrong token'}
28 
29 #print verify_token('d29xdW5pYW5tYWlsZWdlYmlhb3xyZWJvb3R8YWRtaW58MTUwMTYyNDYwMQ==')

  如果通过登录的方式,就把token传递给前端了,前端可以使用自己生成url的方法来使请求的url带上token的字段

  首先定义一个myget的方法,来对$.get请求的内容做填丛

1     //定义api请求的方法
2     $.myget = function(url,data,fn){
3         if(localStorage.token){
4             $.get(url+'?access_token'+localStorage.token,data,fn)
5         }else{
6             location.href='/login'
7         }
8     }

  然后在请求listapi时,代替传统的$.api

 1    function getList(){
 2        
 3        $.myget('/listapi','table_name=idc',function(res){
 4             var res = JSON.parse(res)
 5        //$.getJSON('/listapi?table_name=idc',function(res){
 6           var html_str = ''
 7           $.each(res,function(i,j){
 8             html_str += '<tr>'
 9             html_str += '<td>'+j[3]+'</td>'
10             html_str += '<td>'+j[1]+'</td>'
11             html_str += '<td>'+j[2]+'</td>'
12             html_str += '<td><button class="del-btn btn btn-danger btn-xs" data-name="'+j[1]+'" data-id="'+j[0]+'">delete</button></t
13 d>'
14             html_str += '</tr>'
15           })
16        //console.log([$('#idc-list').html()])
17 
18        render_table('my-idc-table',html_str)
19 
20        })
21    }
22 
23 getList()

 

 

绘图展示

  获取内存信息的土著方法:

 1 import time
 2 
 3 
 4 def get_mem():
 5     with open('/proc/meminfo') as f:
 6         total = f.readline().split()[1]
 7         free = f.readline().split()[1]
 8         ava = f.readline().split()[1]
 9         buf = f.readline().split()[1]
10         cache = f.readline().split()[1]
11     print ('free %s ava %s')%(free,ava)
12     
13     
14 while True:
15     get_mem()
16     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 模块

   psutil官网

 

 

 

 

 

 

 

 

 

 

  

 

posted @ 2017-07-26 14:23  IT小工Joey  阅读(431)  评论(0编辑  收藏  举报