1,Flask框架的诞生:
Flask诞生于2010年,是Armin ronacher(人名)用Python语言基于Werkzeug工具箱编写的轻量级Web开发框架。它主要面向需求简单的小应用。
Flask本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展Flask-Mail,用户认证Flask-Login),都需要用第三方的扩展来实现。比如可以用Flask-extension加入ORM、窗体验证工具,文件上传、身份验证等。Flask没有默认使用的数据库,你可以选择MySQL,也可以用NoSQL。其 WSGI 工具箱采用 Werkzeug(路由模块) ,模板引擎则使用 Jinja2 。
可以说Flask框架的核心就是Werkzeug和Jinja2。
Python最出名的框架要数Django,此外还有Flask、Tornado等框架。
虽然Flask不是最出名的框架,但是Flask应该算是最灵活的框架之一,这也是Flask受到广大开发者喜爱的原因。
2,Flask部分扩展包:
Flask-SQLalchemy:操作数据库;
Flask-migrate:管理迁移数据库;
Flask-Mail:邮件;
Flask-WTF:表单;
Flask-Bable:提供国际化和本地化支持,翻译;
Flask-script:插入脚本;
Flask-Login:认证用户状态;
Flask-OpenID:认证;
Flask-RESTful:开发REST API的工具;
Flask-Bootstrap:集成前端Twitter Bootstrap框架;
Flask-Moment:本地化日期和时间;
3,Flask参考网站
中文文档(http://docs.jinkan.org/docs/flask/)
英文文档(http://flask.pocoo.org/docs/0.11/)
4,第一个Hello Flask程序
Flask程序运行过程:
所有Flask程序必须有一个程序实例。
Flask调用视图函数后,会将视图函数的返回值作为响应的内容,返回给客户端。
一般情况下,响应内容主要是字符串和状态码。
当客户端想要获取资源时,一般会通过浏览器发起HTTP请求。
此时,Web服务器使用WSGI(Web Server Gateway Interface)协议,把来自客户端的所有请求都交给Flask程序实例,程序实例使用Werkzeug来做路由分发(URL请求和视图函数之间的对应关系)。
根据每个URL请求,找到具体的视图函数。
在Flask程序中,路由的实现一般是通过程序实例的装饰器实现。
通过调用视图函数,获取到数据后,把数据传入HTML模板文件中,模板引擎负责渲染HTTP响应数据,然后由Flask返回响应数据给浏览器,最后浏览器处理返回的结果显示给客户端。
示例:
#导入Flask类
from flask import Flask
#Flask函数接收一个参数name,它会指向程序所在的模块
'''
注意:name可以传入的参数:
1,字符串:‘hello’,但是‘abc’,不行,因为abc是python内置的模块
2,__name__
不可以插入的参数
1,python内置的模块,re,urllib,abc等
2,数字
'''
app = Flask(__name__)
#装饰器的作用是将路由映射到视图函数index
@app.route('/')
def index():
return 'Hello Flask'
#Flask应用程序实例的run方法启动WEB服务器
if __name__ == '__main__':
app.run()
5,默认的URL和正则URL
@app.route('<URL>')中URL显式支持string、int、float、path 4种类型,隐式支持正则
5.1默认的url
分析源码(在routing.py文件中,大概1092行中)发现url支持以下几种类型
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}
5.2正则URL的实现
第一步,写正则类,继承BaseConverter,将匹配到的值设置为regex的值就可以了
class RegexUrl(BaseConverter):
def __init__(self, url_map, *args):
super(RegexUrl, self).__init__(url_map)
self.regex = args[0]
第二步,把正则类赋值给我们定义的正则规则
app.url_map.converters['re'] = RegexUrl
第三步,在URL中使用正则
@app.route('/regex/<re("[a-z]{3}"):id>')
def regex(id):
return 'id:%s'%id
6,Flask中钩子的理解和应用
钩子是通过装饰器的形式实现的,支持以下四种
- before_first_request:在处理第一个请求前运行
- before_request:在每次请求前运行
- after_request:如果没有未处理的异常抛出,在每次请求后运行
- teardown_request:即使有未处理的异常抛出,在每次请求后运行
应用:
@api.after_request
def after_request(response):
"""设置默认的响应报文格式为application/json"""
# 如果响应报文response的Content-Type是以text开头,则将其改为默认的json类型
if response.headers.get("Content-Type").startswith("text"):
response.headers["Content-Type"] = "application/json"
return response
7,自定义过滤器的步骤如下:
第一步:先定义自定义过滤器函数
def count_substring(string, substring):
return string.count(substring)
第二步:注册自己定义的过滤器
app.jinja_env.filters['count_substring'] = count_substring
第三步:最后在模板文件html中直接使用注册时的键名
{#前面的作为原字符串string,传入的作为子字符串substring#}
{{ 'A long long long long long long longabc string ' | count_substring('long') }}<br/>
8,什么是Werkzeug?
Werkzeug是WSGI协议层工具集。
WSGI本身是一个用来确保你的web应用能够与webserver进行对话,
更重要的是,确保web应用之间能够一起配合工作的协议或约定。
在没有Werkzeug帮助下,用WSGI实现的一个基本“Hello World”应用看起来是这样的:
def application(environ, start_response):
start_response(‘200 OK’, [(‘Content-Type’, ‘text/plain’)])
return [‘Hello World!’]
WSGI应用是你可以调用、传递一个environ字典和一个start_response函数的东西。
environ包含所有的传入信息,start_response函数可以用来指示response的开始。
使用Werkzeug之后,你将不再需要直接处理被提交上来的请求(request)和应答(response)对象。
请求数据获取environ对象,并允许你以一种良好的方式访问environ中的数据。
response对象本身也是一个WSGI应用,提供了很多友好的创建response的方法。
下面的代码演示了如何编写带有response对象的应用:
from werkzeug.wrappers import Response
def application(environ, start_response):
response = Response(‘Hello World!’, mimetype=‘text/plain’)
return response(environ, start_response)
9,flask-script指令第三方扩展
第一种——创建Command子类
Command子类必须定义一个run方法;
举例:创建Hello命令,并将Hello命令加入Manager实例
from flask_script import Manager
from flask_script import Command
from debug import app
manager = Manager(app)
class Hello(Command):
'hello world'
def run(self):
print 'hello world'
manager.add_command('hello', Hello())
def make_shell_context():
return dict(app = app, db=db)
manager.add_command("shell",Shell(make_context=make_shell_context))
if __name__ == '__main__':
manager.run()
第二种——使用Command实例的@command修饰符
from flask_script import Manager
from debug import app
manager = Manager(app)
@manager.command
def hello():
'hello world'
print 'hello world'
if __name__ == '__main__':
manager.run()
第三种——使用Command实例的@option修饰符
复杂情况下,建议使用@option;
可以有多个@option选项参数
10,请求上下文和应用上下文的区别
current_app、g就是应用上下文
requests、session就是请求上下文
手动创建上下文的两种方法:
with app.app_context()
app = current_app._get_current_object()
11,Flask特有的变量和函数
config
你可以从模板中直接访问Flask当前的config对象:
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:xiaoke@127.0.0.1:3306/test'
request:
就是flask中代表当前请求的request对象:
http://127.0.0.1
session
为Flask的session对象
注意:
flask中有三个session:
第一个:数据库中的session,例如:db.session.add()
第二个:在flask_session扩展中的session,使用:from flask_session import Session,使用第三方扩展的session可以把信息存储在服务器中,客户端浏览器中只存储sessionid
第三个:flask自带的session,是一个请求上下文, 使用:from flask import session。自带的session把信息加密后都存储在客户端的浏览器cookie中
url_for()
url_for会根据传入的路由器函数名,返回该路由对应的URL,在模板中始终使用url_for()就可以安全的修改路由绑定的URL,则不比担心模板中渲染出错的链接:
{ {url_for('home')} }
如果我们定义的路由URL是带有参数的,则可以把它们作为关键字参数传入url_for(),Flask 会把他们填充进最终生成的URL中:
{ { url_for('post', post_id=1)} }
/post/1
get_flashed_messages()
这个函数会返回之前在flask中通过flash()传入的消息的列表,
flash函数的作用很简单,可以把由Python字符串表示的消息加入一个消息队列中,再使用get_flashed_messages()函数取出它们并消费掉:
{ %for message in get_flashed_messages()% }
message
{ %endfor% }
网友评论