首页 > 代码库 > 我的python学习--第十二天(一)

我的python学习--第十二天(一)

一、CMDB中关联表之间数据的渲染

  1. 如何将关联表中的id在渲染时显示为name(查)

  2. 添加关联表数据时,如何渲染下拉菜单(增)

  3. 更新数据时,如何渲染下拉菜单并显示当前数据(改)


1.1、将id渲染为name

fields_cabinet=[‘id‘,‘name‘,‘idc_id‘,‘u_num‘,‘power‘]
fields_idc=[‘id‘,‘name‘]

@app.route(‘/cabinet/‘)
def cabinet():
    if not session.get(‘name‘):
        return render_template(‘login.html‘)                                                                                                              
    role = session.get(‘role‘)
    # 通过db文件中的list函数将机柜表中的所有数据查找出来
    cabinets = db.list(‘cabinet‘,fields_cabinet)
    for i in cabinets:
        # 通过单个机柜中的‘idc_id‘获取与之对应的单个机房的信息
        idc = db.list(‘idc‘,fields_idc,i[‘idc_id‘])
        # 将机柜的‘idc_id‘改为机房名
        i[‘idc_id‘] = idc[‘name‘]

    return render_template("cabinetlist.html",cabinets = cabinets)


2.1、渲染下拉菜单(jinja2方法)

前端代码:

<select id=‘idc_id‘ class=‘multiselect dropdown-togglebtn btn-default‘>
<!-- idcs为机房表中的所有信息,从中获取idc并逐个渲染 -->
{% for idc in idcs %}           
    <option value="http://www.mamicode.com/{{ idc.id }}">{{ idc.name }}</option>
{% endfor %}                     
</select>


逻辑端代码:

@app.route(‘/cabinetadd‘,methods = [‘GET‘,‘POST‘])
def cabinetadd():
    if not session.get(‘username‘,None):
        return redirect("/login")
        
    if request.method == ‘GET‘:
        # 获取机房表的数据传给前端
        data = db.list(‘idc‘,fields_idc)
        return  render_template(‘cabinetadd.html‘,idcs=data)
    else:
        ... ...


2.2、渲染下拉菜单(jquery方法)

前端html代码:

<!-- 一个空的select -->
<select id=‘idc_id‘ class=‘multiselect dropdown-toggle btn btn-default‘>
</select>


js代码:

var str = ‘‘
$.getJSON(‘/idc_msg‘,function(data){
    idcs = data[‘result‘]
    for(var i=0;i<idcs.length;i++){
    // 通过拼字符串的方法获取所有的option
    str += ‘<option value="http://www.mamicode.com/‘+idcs[i][‘id‘]+‘">‘+idcs[i][‘name‘]+‘</option>‘
    // 对‘idc_id‘添加数据
    $(‘#idc_id‘).html(str)
    }


逻辑端代码:

@app.route(‘/idc_msg/‘)
def idc_msg():
    if not session.get(‘name‘):
        return render_template(‘login.html‘)
        
    # 获取idc表中的数据
    idcs = db.list(‘idc‘,fields_idc)
    return json.dumps({‘result‘:idcs})


3.1、渲染下拉菜单,并显示当前数据(jinja2方法)

前端代码:

<select id=‘idc_id‘ class=‘multiselect dropdown-toggle btn btn-default‘>
{% for idc in  idcs %}
    <!-- 通过idc表中的数据对option进行渲染,将单个cabinet的‘idc_id‘与渲染好的option对比,
     相同就选中,否则不作操作 -->
    {% if cabinet.idc_id == idc.id %}
     <option  value="http://www.mamicode.com/{{ idc.id }}" selected="selected">{{ idc.name }}</option>
    {% else %}
     <option  value="http://www.mamicode.com/{{ idc.id }}" >{{ idc.name }}</option>
    {% endif %}
{% endfor %}
</select>


逻辑端代码:

@app.route(‘/cabinetupdate‘,methods=[‘GET‘,‘POST‘])
def cabinet_update():
    ... ...
    ... ...
    if request.method == ‘GET‘:
        # 从list页面跳转到update页面是会传递单条数据的‘id‘
        id = request.args.get(‘id‘ )
        # 单个机柜数据
        cabinet = db.list(‘cabinet‘,fields,id)
        # 所有的机房数据
        idcs = db.list(‘idc‘,idc_fields)   
        return render_template(‘cabinet/cabinetupdate.html‘,cabinet=cabinet,idcs=idcs)


3.2、渲染下拉菜单,并显示当前数据(jquery方法)

前端html代码:

<!-- 一个空的select -->
<select id=‘idc_id‘ class=‘multiselect dropdown-toggle btn btn-default‘>
</select>


前端js代码:

$(‘.update‘).click(function(){
    var id=$(this).attr(‘data-id‘)
    var url = "/cabinet_update_msg?id="+id
    var str = ‘‘
    
    // 从‘/idc_msg‘回调函数中获取所有的机房数据,拼接成option字符串,在select中显示
    $.getJSON(‘/idc_msg‘,function(data){
        idcs = data[‘result‘]
        for(var i=0;i<idcs.length;i++){
            str += ‘<option value="http://www.mamicode.com/‘+idcs[i][‘id‘]+‘">‘+idcs[i][‘name‘]+‘</option>‘
            }
        $(‘#idc_id‘).html(str)

        // 从‘/cabinet_update_msg‘中获取单个机柜信息,并渲染
        $.getJSON(url,function(data){
            if (data[‘code‘] == 0){
                cabinet = data[‘result‘]
                $(‘#id‘).val(cabinet[‘id‘])
                $(‘#name‘).val(cabinet[‘name‘])
                // 当option中value与机柜的‘idc_id‘相同时,添加属性使其被选中
                $("#idc_id option[value=http://www.mamicode.com/‘"+cabinet[‘idc_id‘]+"‘]").attr(‘selected‘,true)
                $(‘#u_num‘).val(cabinet[‘u_num‘])
                $(‘#power‘).val(cabinet[‘power‘])
            }else{
                $(‘#errmsg‘).html(‘fail‘)
            }
        })
    })
})


逻辑端数据:

# 获取所有机房信息
@app.route(‘/idc_msg/‘)
def idc_msg():
    if not session.get(‘name‘):
        return render_template(‘login.html‘)
    idcs = db.list(‘idc‘,fields_idc)
    return json.dumps({‘result‘:idcs})


# 获取单个机柜信息
@app.route(‘/cabinet_update_msg/‘)
def cabinet_update_msg():
    id = request.args.get(‘id‘)
    cabinet = db.list(‘cabinet‘,fields_cabinet,id)
    return json.dumps({‘code‘:0,‘result‘:cabinet})



Flask配置文件管理


Flask有一个内置的全局字典app.config,使用这个全局字典进行管理


1、直接配置(不推荐使用)

In [1]: from flask import Flask

In [2]: app = Flask(__name__)

# 直接通过字典的方式进行赋值
In [3]: app.config[‘host‘] = ‘localhost‘

In [4]: app.config.get(‘host‘)
Out[4]: ‘localhost‘


2、通过环境变量加载配置

[root@yaoliang day_12]# tail config.py 
# 配置键必须为大写字母,否则无效
HOST = ‘localhost‘

[root@yaoliang day_12]# export CONFIG_SET=/data/python/day_12/config.py
... ...

In [3]: app.config.from_envvar(‘CONFIG_SET‘)           # 从全局变量中读取文件中的数据
Out[3]: True

In [4]: app.config.get(‘HOST‘)
Out[4]: ‘localhost‘


3、通过对象加载(推荐使用)

[root@yaoliang day_12]# cat config2.py 
class DevelopmentConfig():
    SQLALCHEMY_DATABASE_URI=‘mysql://wd:123456@192.168.1.11/test‘

class ProductionConfig():
    SQLALCHEMY_DATABASE_URI=‘mysql://wd:123456@192.168.1.11/devops‘

# 将类写成字典的形式存储
config = {
    ‘dev‘ : DevelopmentConfig,
    ‘pro‘ : ProductionConfig,
    ‘default‘ : DevelopmentConfig
}
... ...
In [3]: from config2 import *

In [4]: app.config.from_object(‘DevelopmentConfig‘)    # 方法一,直接获取对象中定于类

In [5]: app.config.get(‘SQLALCHEMY_DATABASE_URI‘) 
Out[5]: ‘mysql://wd:123456@192.168.1.11/test‘

In [6]: app.config.from_object(config[‘pro‘])          # 方法二,通过获取对象中字典定义的类,效果同上

In [7]: app.config.get(‘SQLALCHEMY_DATABASE_URI‘)
Out[7]: ‘mysql://wd:123456@192.168.1.11/devops‘


4、通过配置文件

[root@yaoliang day_12]# tail config.py                 
HOST = ‘localhost‘
... ...

In [3]: app.config.from_pyfile(‘config.py‘)     # config.py必须与执行文件在同一目录
Out[3]: True

In [4]: app.config.get(‘HOST‘)
Out[4]: ‘localhost‘


5、通过python的ConfigParse模块

In [1]: cat config.py                           # 通过[]对配置文件进行分组,config.py可以在任意位置
[test]                                          # section
port = 1111                                     # option
path = /data/test/log

[web]
port = 1112
path = /data/web/log
 
In [2]: import ConfigParser
 
In [3]: cf = ConfigParser.ConfigParser()    # 实例化一个对象
 
In [4]: cf.read(‘config.py‘)                # 读取文件所有内容
Out[4]: [‘config.py‘]
 
In [5]: host1 = cf.get(‘info‘,‘host‘)       # 通过get(‘section‘,‘option‘)来获取数据
 
In [6]: host2 = cf.get(‘test‘,‘host‘)
 
In [7]: print host1,host2
‘localhost‘ ‘127.0.0.1‘

# 其他用法
In [8]: cf.sections()                       # 获取所有的section
Out[8]: [‘test‘, ‘web‘]

In [9]: cf.items(‘test‘)                    # 通过section获取所有的option
Out[9]: [(‘port‘, ‘1111‘), (‘path‘, ‘/data/test/log‘)]

In [10]: cf.add_section(‘development‘)      # 添加section

In [11]: cf.set(‘development‘,‘port‘,1113)  # 设置section中的option

In [12]: cf.set(‘development‘,‘path‘,‘/data/development/log‘)

In [13]: fo = open(‘config.py‘,‘w‘)         # 打开config.py配置文件

In [14]: cf.write(fo)                       # 将新的section写入

In [15]: fo.close()

In [16]: cat config.py                      # 显示新配置已经写入
[test]
port = 1111
path = /data/test/log

[web]
port = 1112
path = /data/web/log

[development]
port = 1113
path = /data/development/log


我的python学习--第十二天(一)