flaskFlask专题学习flask

Flask框架知识系列之一

2017-12-01  本文已影响243人  晓可加油

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中钩子的理解和应用

钩子是通过装饰器的形式实现的,支持以下四种

  1. before_first_request:在处理第一个请求前运行
  2. before_request:在每次请求前运行
  3. after_request:如果没有未处理的异常抛出,在每次请求后运行
  4. 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% }
上一篇下一篇

猜你喜欢

热点阅读