Flask是非常流行的Python Web框架,它能如此流行,原因主要有如下几点:
●有非常齐全的官方文档,上手非常方便。
●有非常好的扩展机制和第三方扩展环境,工作中常见的软件都会有对应的扩展。自
已动手实现扩展也很容易。
●社区活跃度非常高。
●微框架的形式给开发者更大的选择空间。
●Pocoo团队出品,Flask 和相关依赖( Jinja2、Werkzeug )的设计很优秀。比如使用装
饰器配置路由、用Blueprint实现模块化、请求/应用上下文等。
Flask主要依赖三个库。
●Jinja2: 默认的模板引擎。
●Werkzeug:一个包含WSGI、路由、调试的工具集。
●Itsdangerous: 基于Django签名模块( htp://it.ly/28QV7Fb)的签名实现。
HelloWorld
# coding=utf-8
from flask import Flask
#app是Flask的实例,它接收包或者模块的名字作为参数,但一般都是传递
#__name__。让flask.helpers.get_root_path函数通过传入这个名字确定
#程序的根目录,以便获得静态文件和模板文件的目录
app = Flask(__name__)
#使用app.route装饰器会将URL和执行的视图函数的关系保存到app.url_map
#属性上。处理URL和视图函数的关系的程序就是路由,这里的视图函数就是hello_ world。
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__=='__main__':
#执行app.run就可以启动服务了
app.run(host='127.0.0.1',port=8080)
app.run(host='127.0.0.1',port=8080,debug=True) 加入debug可以自动重启
#host='0.0.0.0'用外网访问,但要debug=False app.run(host='0.0.0.0',port=8080,debug=False)
配置管理
复杂的项目需要配置各种环境。如果设置项很少,可以直接硬编码进来,比如下面的方式:
app = Flask(__ name___ )
app. config[ ' DEBUG'] = True
app.config是flask.config.Config 类的实例,继承自Python内置数据结构dict,所以可以使用
update方法:
app. config. update(
DEBUG=True,
SECRET_ KEY='...'
)
如果设置选项很多,想要集中管理设置项,应该将它们存放到一个文件里面。app.config 支
持多种更新配置的方式。假设现在有个叫作settings.py的配置文件,其中的内容如下:
A=1
HTTP方法
HTTP有多个访问URL方法,默认情况F,路由只回应GET请求,但是通过app.route装饰器传递methods参数可以改变这个行为:
@app.route('/login',methods=['GET','POST'])
HTTP方法和使用场景:
GET:获取资源,GET操作应该是幂等的。(幂等表示在相同的数据和参数下,执行一次或多次产生的效果是一样的)
HEAD:想要获取信息,但是只关心消息头。应用应该像处理GET请求一样来处理它,但是不返回实际内容。
POST:创建一个新的资源。
PUT:完整地替换资源或者创建资源。PUT操作虽然有副作用,但应该是幂等的。
DELETE:删除资源。DELETE 操作有副作用,但也是幕等的。
OPTIONS:获取资源支持的所有HTTP方法。
PATCH:局部更新,修改某个已有的资源。
唯一URL
@app.route('/projects/')
def projects():
return 'The project page'
@app.route('/about')
def about():
return 'The about page'
上述例子很像一个文件系统中的文件夹,访问一个结尾不带斜线的URL会被重定向到带斜线的规范的URL上去,这样也有助于避免搜索引擎索引同一个页面两次。
URL结尾不带斜线,很像文件的路径,但是当访问带斜线的URL ( /about/ )会产生一个404“Not Found”错误。
构造URL
用url_for 构建URL,它接受函数名作为第-一个 参数,也接受对应URL规则的变量部分的命名参数,未知的变量部分会添加到URL末尾作为查询参数。构建URL而不选择直接在代码中拼URL的原因有两点:在未来有更改的时候只需要一次性修改URL,而不用到处去替换;URL构建会转义特殊字符和Unicode数据,这些工作不需要我们自己处理。
from flask import Flask,url_for
app=Flask(__name__)
@app.route('/item/1/')
def item(id):
pass
with app.test_request_context():
print(url_for('item',id='1'))
print(url_for('item', id=2,next='/'))
跳转和重定向
跳转(状态码301)多用于旧网址在废弃前转向新网址以保证用户的访问,有页面被永久性移走的概念。重定向(状态码302)表示页面是暂时性的转移。但是也不建议经常性使用重定向。在Flask中它们都是通过flask.redirect实现的:
redirect(location)#默认是302
redirect(location,code=301)#通过code参数可以指定状态码
Flask还支持303、305、 307 重定向,但是较少被用到。
存放配置的config.py
DEBUG=False
try:
from local_settings import *
except ImportError:
pass
local_ settings.py 文件是可选存在的,它不进人版本库。这是常用的通过本地配置文件重载版本库配置的方式。
from flask import Flask,request,abort,redirect,url_for
app=Flask(__name__)
app.config.from_object('config')
@app.route('/people/')
def people():
name=request.args.get('name')
if not name:
return redirect(url_for('login'))
user_agent=request.headers.get('User-Agent')#存放了请求头的信息,可以获取UA值
return 'Name:{0};UA:{1}'.format(name,user_agent)
@app.route('/login/',methods=['GET','POST'])
def login():
if request.method=='POST':#请求的类型
user_id=request.form.get('user_id')
return 'User:{} login'.format(user_id)
else:
return 'Open Login page'
@app.route('/secret/')
def secret():
abort(401)#放弃请求,并返回错误代码401,表示禁止访问,之后的语句永远不会执行
print("This is never executed")
if __name__=='__main__':
app.run(host="127.0.0.1",port=8000,debug=app.debug)
Response
from flask import Flask,make_response
app=Flask(__name__)
@app.route("/hello")
def hello():
"""
默认
#status code 200,404,301
#content-type http headers
#content-type=text/html
:return:
"""
headers={
'content-type':'text/plain',#控制返回内容
'location':'http://www.bing.com'
}
"""
response=make_response('<html></html>', 404)
response=make_response('<html></html>', 301)
response.headers=headers
return response
"""
#或直接return
return "<html></html>",301,headers
if __name__ == '__main__':
app.run(host="0.0.0.0",port=8080,debug=True)