• 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'u5929u6d25', u'1810'), (13L, u'u6cb3u5317', u'188'), (14L, u'u5317u4eac', u'1999'), (15L, u'u5317u4eac', u'199'), (16L, u'u53f0u6e7e', u'111'), (20L, u'u6d77u5357', 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官网

      

  • 相关阅读:
    几个常用排序的代码实现堆排序|快排|归并排序 Marathon
    0647回文子串 Marathon
    任意输入一个日期输出是当年的第几天星期几
    从输入URL到浏览器显示页面发生了什么
    常用链接整理
    computed 与 method
    将博客搬至CSDN
    leetcode_Two Sum
    VC++6.0与Office2010冲突解决方案
    C&C++_malloc函数
  • 原文地址:https://www.cnblogs.com/nopnog/p/7239463.html
Copyright © 2020-2023  润新知