Flask(一)

Flask介绍

Flask是一个用Python编写的Web应用程序框架。 它由Armin Ronacher开发,他领导着一个名为Pocco的Python爱好者的国际组织。 Flask基于Werkzeug WSGI工具包和Jinja2模板引擎。

WSGI

Web服务器网关接口(WSGI)已被采纳为Python Web应用程序开发的标准。 WSGI是Web服务器和Web应用程序之间通用接口的规范。

WERKZEUG

它是一个WSGI工具包,它实现了请求,响应对象和其他实用程序功能。 这可以在其上构建Web框架。 Flask框架使用Werkzeug作为其一个基础模块之一。

浅谈Django、Flask和Tornado区别?

  • Django:简单的说Django是一个大而全的Web框架,内置了很多组件,ORM、admin、Form、

ModelForm、中间件、信号和缓存等。基于wsgi协议部署的,使用wsgiref模块实现此协议;

  • Flask:微型的小而精的Web框架,可扩展性强,内置的组件很少,需要引入第三方组件实现功能业务,如果开发简单的项目,使用Flask比较快速和方便。如果开发大型项目,需要引入大量的第三方组件,这时Flask会越来越像Django框架。基于wsgi协议部署,使用werkzeug模块实现此协议,模板系统由 Jinja2提
    供。
  • Tornado:是一个轻量级的Web框架,可扩展性强,用于快速开发简单程序,用于强大的异步非阻塞
    和内置WebSocket功能。

Flask快速入门

安装

在创建项目之前我们需要安装Flask,当然在这之前应该创建虚拟环境,在虚拟环境中安装Flask,在这里就不多说:

1
pip install Flask

基本使用

1
2
3
4
5
6
7
8
9
10
11
12
from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello_world():
return 'Hello World!'


if __name__ == '__main__':
app.run()

参数介绍:

flask(import_name, static_url_path, template_folder, instance_path, instance_relative_config, root_path, static_folder)

  • import_name:要创建的app的名称
  • static_url_path:用来指定url路径中static代表的路径,可以看作别名,类似Django中的STATICFILES_DIRS配置,static用来存放静态文件,默认为static
  • static_folder:指定静态文件的存放目录,默认为static
  • template_folder:指定模板文件的存放目录,默认为templates
  • root_path:应用搜索static、templates等目录的根目录,也就是说,会在root_path指定的目录下搜索static、templates文件夹
    • 如果你没有指定root_path,那么Flask就会将import_name所在的目录作为root_oath
  • instance_relative_config:这个参数只在为app生成配置的时候有用,app在生成Config的时候,make_config传递进入的是root_path还是在实例化app时指定的instance_path
  • instance_path:instance_relative_config=True的时候该参数才有效 ,如果instance_path=None(默认),默认搜索配置文件的路径就是root_path下的instance/目录

配置文件

flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为 :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
'DEBUG': get_debug_flag(default=False), # 是否开启Debug模式
'TESTING': False, # 是否开启测试模式
'PROPAGATE_EXCEPTIONS': None,
'PRESERVE_CONTEXT_ON_EXCEPTION': None,
'SECRET_KEY': None,
'PERMANENT_SESSION_LIFETIME': timedelta(days=31),
'USE_X_SENDFILE': False,
'LOGGER_NAME': None,
'LOGGER_HANDLER_POLICY': 'always',
'SERVER_NAME': None,
'APPLICATION_ROOT': None,
'SESSION_COOKIE_NAME': 'session',
'SESSION_COOKIE_DOMAIN': None,
'SESSION_COOKIE_PATH': None,
'SESSION_COOKIE_HTTPONLY': True,
'SESSION_COOKIE_SECURE': False,
'SESSION_REFRESH_EACH_REQUEST': True,
'MAX_CONTENT_LENGTH': None,
'SEND_FILE_MAX_AGE_DEFAULT': timedelta(hours=12),
'TRAP_BAD_REQUEST_ERRORS': False,
'TRAP_HTTP_EXCEPTIONS': False,
'EXPLAIN_TEMPLATE_LOADING': False,
'PREFERRED_URL_SCHEME': 'http',
'JSON_AS_ASCII': True,
'JSON_SORT_KEYS': True,
'JSONIFY_PRETTYPRINT_REGULAR': True,
'JSONIFY_MIMETYPE': 'application/json',
'TEMPLATES_AUTO_RELOAD': None,
}

如果需要修改配置,可以根据下面的方式修改:

  1. 方式一

    app.config[DEBUG]=True

    注意:由于Config对象本质上是字典,可以使用app.config.update(…)

  2. 方式二

    app.config.form_pyfile(‘python文件名称’)

    如:settings.py

    1
    DEBUG = True

    app.config.from_pyfile(‘settings.py’)

  3. 方式三

    app.config.form_envvar(‘环境变量名称’)

    环境变量的值为python文件名称,内部调用form_pyfile方法

  4. 方式四

    app.config.form_json(‘json文件名称’)

    json文件必须是json格式,内部会执行json.loads

  5. 方式五

    app.config.from_mapping({‘DEBUG’:True})

  6. 方式六(推荐使用)

    app.config.from_object(‘python类或类的路径’) #默认从根目录开始

    • settings.py文件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    class Config(object):
    """应用程序配置类"""
    # 开启调试模式
    DEBUG = True

    # logging等级
    LOGGIONG_LEVEL = logging.DEBUG
    # flask-sqlalchemy使用的参数
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@127.0.0.1:3306/ehome'
    # 追踪数据库的修改行为,如果不设置会报警告,不影响代码的执行
    SQLALCHEMY_TRACK_MODIFICATIONS = True
    # 显示sql语句
    # SQLALCHEMY_ECHO = True


    class DevelopConfig(Config):
    """开发阶段下的配置子类"""
    # logging等级
    LOGGIONG_LEVEL = logging.DEBUG


    class UnitTestConfig(Config):
    """单元测试配置子类"""
    # logging等级
    LOGGIONG_LEVEL = logging.DEBUG
    SQLALCHEMY_DATABASE_URI = 'mysql://root:root@127.0.0.1:3306/ehome_test'


    class ProductionConfig(Config):
    """生产环境下配置子类"""
    # logging等级
    LOGGIONG_LEVEL = logging.WARNING
    DEBUG = False
    SQLALCHEMY_DATABASE_URI = 'mysql://root:root@47.106.93.190:3306127.0.0.1:3306/ehome'

    注意:settings.py文件默认路径要放在程序root_path目录,如果instance_relative_config为True,则就是instance_path目录

路由系统

1
2
3
4
5
# @app.route('/user/<username>')
# @app.route('/post/<int:post_id>')
# @app.route('/post/float:post_id')
# @app.route('/post/path:path')
# @app.route('/login', methods=['GET', 'POST'])

以上五种路由是最常用的,下面再来了解一下路由的执行过程:

1
2
3
@app.route('/', methods=['GET','POST'], endpoint='hello')
def index():
return 'Hello World!'
  1. 当执行app.route(‘/‘,methods=[‘GET’,’POST’],endpoint=’hello’)时会执行如下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    def route(self, rule, **options):
    # self 是app对象
    # rule = '/'
    # options = {methods=['GET','POST'], endpoint='hello'}
    def decorator(f):
    endpoint = options.pop('endpoint', None)
    self.add_url_rule(rule, endpoint, f, **options)
    return f
    return decorator

    实质就是decorator = app.route(‘/‘,methods=[‘GET’,’POST’],endpoint=’hello’)

  2. 有返回值后,实际上就是@decorator,这次执行decorator函数会把index函数当做参数传入

我们这里写的路由其实就是执行了app.add_url_rule(‘/‘, ‘hello’, index, methods=[‘GET’,’POST‘])这句代码,这就跟django框架一样了

在来看看 @app.route和app.add_url_rule常用参数(只是部分):

  • rule:URL规则

  • view_func:视图函数名称

  • defaults=None:默认值,当URL中无参数,函数需要参数时,使用defaults={‘k’:’v’}为函数提供参数

  • endpoint=None:名称,用于反向生成URL,即: url_for(‘名称’)

  • methods=None:允许的请求方式,如:[‘GET’,’POST’]

  • strict_slashes=None:对URL最后的 / 符号是否严格要求

  • redirect_to=None:重定向到指定地址,如下:

    1
    2
    3
    4
    5
    @app.route('/index/<int:nid>', redirect_to='/home/<nid>')

    def func(adapter, nid):
    return "/home/888"
    @app.route('/index/<int:nid>', redirect_to=func)

所有的路由系统都是基于一下对应关系来处理 :

1
2
3
4
5
6
7
8
9
DEFAULT_CONVERTERS = {
'default': UnicodeConverter,
'string': UnicodeConverter,
'any': AnyConverter,
'path': PathConverter,
'int': IntegerConverter,
'float': FloatConverter,
'uuid': UUIDConverter,
}

注意:此配置在werkzeug包下routing.py文件中

以上的路由其实已经够用了,但是不排除有一些比较另类的,这时可以考虑自定制正则路由匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
from flask import Flask, views, url_for
from werkzeug.routing import BaseConverter

app = Flask(import_name=__name__)


class RegexConverter(BaseConverter):
"""
自定义URL匹配正则表达式
"""

def __init__(self, url_map, regex):
super(RegexConverter, self).__init__(url_map)
self.regex = regex

def to_python(self, value):
"""
路由匹配时,匹配成功后传递给视图函数中参数的值
:param value:
:return:
"""
return int(value)

def to_url(self, value):
"""
使用url_for反向生成URL时,传递的参数经过该方法处理,返回的值用于生成URL中的参数
:param value:
:return:
"""
val = super(RegexConverter, self).to_url(value)
return val


# 为app中的url路由添加正则表达式匹配
app.url_map.converters['regex'] = RegexConverter


@app.route('/index/<regex("\d+"):nid>')
def index(nid):
print(url_for('index', nid='666'))
return 'Index'

请求和响应

请求相关信息
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# request.method
# request.args
# request.form
# request.values
# request.cookies
# request.headers
# request.path
# request.full_path
# request.script_root
# request.url
# request.base_url
# request.url_root
# request.host_url
# request.host
# request.files
# obj = request.files['the_file_name']
# obj.save('/var/www/uploads/' + secure_filename(f.filename))
响应相关信息
1
2
3
4
5
6
7
8
9
10
# return '字符串'
# return render_template('html模板路径',**{})
# return redirect('/index.html')

# response = make_response(render_template('index.html'))
# response是flask.wrappers.Response类型
# response.delete_cookie('key')
# response.set_cookie('key', 'value')
# response.headers['X-Something'] = 'A value'
# return response
-------------本文结束感谢您的阅读-------------

本文标题:Flask(一)

文章作者:GavinLiu

发布时间:2018年04月08日 - 20:04

最后更新:2018年04月09日 - 23:04

原始链接:http://gavinliu4011.github.io/post/735be50e.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

请博主吃个鸡腿吧
0%