人生本来就是一场即兴的演出,没有做不成的梦,只有不愿早醒的人。    Hello Python - day4!

 

  • Flask框架的简介
  1. 官方的一些连接文档
1 http://flask.pocoo.org/ 官网
2 http://dormousehole.readthedocs.org/en/latest/ 中文官网 
3 http://www.pythondoc.com/ 很全的文档
4 http://docs.jinkan.org/docs/flask/ 很全面
  1. 环境部署
1 安装Virtualenv——虚拟环境能够隔离不同python版本的干扰
2 pip install virtualenv                     # 直接pip安装
3 mkdir myproject # 创建项目环境 
4 cd myproject 
5 virtualenv venv 
6 chmod +x ./venv/bin/activate 
7 ./venv/bin/activate 或
8 source /venv/bin/activate  # 每次运行项目时需要激活环境
  1. 源码安装
1 wget https://pypi.python.org/packages/source/F/Flask/Flask-0.10.tar.gz --no-check-certificate 
2 tar zxvf Flask-0.10.tar.gz 
3 cd Flask 
4 virtualenv venv --distribute 
5 chmod +x ./venv/bin/activate 
6 ./venv/bin/activate 
7 python setup.py develop
  1. pip直接安装
pip install Flask
  • Flask简单的小实例剖析
  1. Flask应用的小实例
1 vim hello.py  
2 
3 from flask import Flask  # 导入Flask模块
4 app = Flask(__name__)   # 定义flask的实例。可理解为类实例化的对象,对象名可以任意,常用app。
5 @app.route('/')   # 用@app. route() 装饰器定义访问 URL
6 def index():   # 执行任务的函数
7   return 'hello world!' 
8 if __name__ == '__main__':  # 执行本文件时,才能执行app.run(),外部import是不能执行的
9   app.run(host='0.0.0.0',port=5000,debug=True)   # 启动服务,定义监听ip,端口,并开启调试 ,默认flask是监听 127.0.0.1的5000端口
  1. 运行服务和访问测试
1 运行服务
2 $ python hello.py 
3     * Running on http://0.0.0.0:5000/ 
4 访问测试
5 curl http://192.168.1.250:5000
6     hello world
  • Flask的路由(URL)基本设置
  1. 简单的模型
1 简单明了的uri方便记忆,给用户良好的体验。route()装饰器用于把一个函数绑定到一个URL
 2 
 3     @app.route('/')  # 为index函数绑定访问url,访问地址:http://ip, 结果Index Page
 4     @app.route('/index')  # 同一个函数可以绑定多个URL
 5     def index():   # URL绑定的函数
 6       return 'Index Page'
 7 
 8     @app.route('/hello')  # 为hello函数绑定访问url,访问地址:http://ip/hello,结果为Hello World
 9     def hello():
10       return 'Hello World'
  1. 通过变量定义URL---url变量名必须和绑定函数的形参名一致
1 @app.route('/user/<string:username>') # uri定义了参数,访问http://ip/user/guanqing
2 def index(username):
3   return 'welcome %s' % username
4 
5 @app.route('/post/<int:post_id>')  # 访问http://ip/post/28 , init把输入的参数转换为整数型
6 def post(post_id):
7   return 'Post id is %d' % post_id
  1. URL反斜杠之间的区别
1 1 # URL不带 / ,访问http://ip/hello时返回200, 访问http://ip/hello/ 时返回404
2 2 @app.route('/hello')
3 3 def hello_world():
4 4   return 'Hello world!'
5 5 
6 6 # 带 / ,访问http://ip/hello时301跳转到http://ip/hello/ 访问http://ip/hello/时返回200
7 7 @app.route('/hello/')
8 8 def hello_world():
9 9   return 'Hello world!'
  • URL传参及request接受参数的常用方式
  1. 通过method(GET,POST,PUT等)方式传参---restful API思想
1 #!/usr/bin/env python
 2 #coding:utf-8
 3 
 4 from flask import Flask,render_template,request
 5 
 6 app=Flask(__name__)
 7 @app.route('/task/',methods=['GET','POST','PUT'])
 8 def task_list():
 9   if request.method == 'GET':  # get请求,http://ip:port/task?name=guanqing
10     name = request.args.get("name")  # request.args.get('key')获取get请求传来的参数
11   elif request.method == 'POST'  # post请求:curl http://ip:port/task/ -d "name=guanqing"  -X POST
12     name = reqeust.form.get('name')  # request.form.get('key')获取post请求传来的参数
13   elif request.method == 'PUT'  # PUT 请求:curl http://ip:port/task/ -d "name=guanqing" -X PUT
14     name = request.form.get('name')  # 同POST方式
15   return  "User is %s"  % name
  1. 定义函数形参与URL变量传参(可结合不定长参数)--- url变量名必须和绑定的函数的形参一致
1 @app.route('/task/<string:username>/')   # curl  http://ip:port/task/guanqing/
 2 def task_detail(username): 
 3 return "User is %s" % username 
 4 
 5 @app.route('/task/<string:username>/',methods=['GET','POST','PUT']) # 函数参数+method传参
 6 def task(username):
 7 if request.method == 'GET':
 8 age = request.args.get('age')
 9 elif request.method == 'POST':
10 age = request.form.get('age')
11 elif request.method == 'PUT':
12 age = request.form.get('age')
13 return "User is %s, and age is %s" % (username,age)
14 
15 if __name__=='__main__': 
16 app.debug=True 
17 app.run(host='0.0.0.0',port=5001)
  • 应用场景
  1. 第一种通过method请求传参的方式的结果 --- api,ajax等场景用的比较多
1 $curl http://192.168.1.251:5001/task/?name=guanqing
 2 User is guanqing
 3 
 4 注意:多个参数 curl "http://192.168.1.251:5001/task/?name=guanqing&age=28"
 5 多个参数用&连接,在shell中&属于特殊字符,故curl请求时,需要加 “”
 6 
 7 $curl http://192.168.1.251:5001/task/ -d "name=guanqing" -X PUT
 8 User is guanqing
 9 
10 # 多个参数,-d “name=guanqing&age=28”
  1. 第二种通过定义函数形参的方式的结果 --- web场景用的
    1 $curl http://192.168.1.251:5001/task/guanqing    User is
  • jinja2模板 -- 基本应用
  1. jinja2相关的官方链接
1 http://niwibe.github.io/django-jinja/   官网
2 http://docjinkan.org/docs/jinja2/    中文文档
3 http://jinja.pocoo.org/docs/dev/intro/  英文版
4 http://www.oschina.net/question/5189_3943    不明觉厉
5 http://www.pythonfan.org/docs/python/jinja2/zh/templates.html      中文官方文档,详细
  1. jinja2相关的概述以及介绍和安装
1 介绍:
 2     Jinja是基于python语言实现的模板引擎,功能比较类似于于PHP的smarty,J2ee的Freemarker和velocity。 
 3 
 4 模板语言:
 5     一种被设计出来自动生成文档的简单文本格式。模版语言中,把一些变量传给模版,替换模版特定位置上预先定义好的展位变量名。其中{{}}来渲染变量,{%%}定义控制代码如if,for等
 6 
 7 运行需求: 
 8     Jinja2需要Python2.4以上的版本。 
 9 安装:
10     按照Jinja有多种方式,你可以根据需要选择不同的按照方式。 flask和Django框架中自带来jinja2模版
11 Python安装:
12     #sudo easy_install Jinja2 
13     #sudo pip install Jinja2
  • jinja2的基本语法
  1. 获取普通变量的值
    后端传来的是单个字符串或数字变量: eg: user=“guanqing” 
  2. 获取对象的值
1 后端传来的是列表: eg:user=['guanqing',28]
2 调用: {{user[0]}}  # 列表元素个数是不确定的,实际生产中用for循环
3 
4 后端传来的是单个字典: eg: user={'name':'guanqing','age':28}
5 调用: {{user.name}}  或 {{user['name']}}
  1. for循环语句
1 for 循环语句:
 2 字典的for循环
 3 users={'name':'guanqing','age':28,‘name’:‘wukun’,‘age’:30}
 4 {% for k,v in users.iteritems() %}
 5     <li><a data={{k}}>{{v}}</a></li>
 6 {% endfor %}
 7 
 8 列表的for循环
 9 users=['zhangsan','lisi','wangwu']
10 {% for user in users %}
11     <li>{{user}}</li>
12 {% endfor %}
13 
14 列表中嵌套字典  ---- 非常常用
15 result=[{'name':'guanqing','age':28,‘name’:‘wukun’,‘age’:30}]
16 {% for user in result %}
17         <li>{{user['name']}}</li>
18         <li>{{user.age}}</li>
19 {% endfor %}
  1. if语句
1 {%  if  user %}
 2 ……
 3 {% else %}
 4 ……
 5 {% endif %}
 6 
 7 
 8 eg:
 9 <td><strong>
10 {% if result.role==0 %}
11      超级管理员
12 {% else %} 
13       普通用户
14  {% endif %}
15 </strong></td>
  • jinja2语法的在实际生产中的使用实例 --- jinja2的数据在js中调用的方式和html中一样
  1. 后端处理部分,传给前端一个数据
1 cat app.py
2     @app.route("/user/list",methods=['GET','POST'])
3     def user_list():
4         result=[{'id':1,'name':'guanqing','email':'guanqing@qq.com','role':0},{'id':2,'name':'wukun','email':'wukun@163.com','role':1}]   # 列表中套字典的使用场景很多
5         return render_template('user_list.html',users=result)  # 将数据传jinja2模板
  1. 前端HTML接受数据并渲染
1 cat user_list.html
 2 <table class="table table-bordered table-striped">
 3     <thead>
 4         <tr>
 5             <th scope="col">姓名</th>
 6             <th scope="col">Email</th>      
 7             <th scope="col">操作</th>  
 8          </tr>
 9     </thead>
10  <body>
11     {% for user in users %}    # 循环遍历列表
12         <tr id="_con_tr" class="odd gradeX">
13             <td>{{user['name']}}</td>
14             <td>{{user['email']}}</td>   # 获取到每次遍历列表字典对应的值
15             <td>{% if user['role'] == 0 %}超级管理员{%else}普通用户{% endif %}</td>
16             <td>
17 # 涉及到了更新,删除操作就需要知道该条记录的ID,就给对应的按钮加一个属性,值为id
18                 <button class='btn btn-primary btn-sm' data-id='{{user['id']}}'>更新</button>
19                  <button class='btn btn-primary btn-sm' data-id='{{user['id']}}'>删除</button>
20             </td>
21           </tr>
22      {% endfor %}
23  </body>
24 </table>
  1. 未完。