一。flask的形成。
flask是一个基于python并且以来jinja2模板和werkzeug wsgi服务器的一个微型框架。
安装了flask模块就代表安装了wekzeug,所以先安装flask.
pip install flask
而werkzeug 的使用可以参考下面:
from wsgiref.simple_server import make_server def mya(environ, start_response): print(environ) start_response('200 OK', [('Content-Type', 'text/html')]) if environ.get('PATH_INFO') == '/index': with open('index.html','rb') as f: data=f.read() elif environ.get('PATH_INFO') == '/login': with open('login.html', 'rb') as f: data = f.read() else: data=b'<h1>Hello, web!</h1>' return [data] if __name__ == '__main__': myserver = make_server('', 8011, mya) print('监听8011') myserver.serve_forever()
二。flask启动分析。
基本的flask的使用如下:
from flask import Flask app=Flask(__name__) @app.route('/') def index(): return "ok" if __name__ == '__main__': #本质是 run_simple(host, port, app, **options) #app(),对象加(),执行__call__ app.run()
当app.run运行的时候,首先生成类,类的__call__方法首先创建运行的就是wsgi_app方法,首先把运行环境搭建。
在app中的run方法本质就是执行run_simple方法,run_simple方法所做的就是werkzeug.serving中的。
三。flask中的4剑客,
和django中一样flask也有4个视图函数,对应关系如下:
四。flask的配置文件方式。
当flask需要配置文件的时候,有以下主要的四种方式:
1.直接通过app=flask(__name__),中的app,修改其中参数。:
app.debug=True app.secret_key="123123"
2.以字典的形式修改其中的cinfig
app.config['DEBUG']=True
3.以文件的形式
app.config.from_pyfile("settings.py")
setting.py
DEBUG = True
4.通过文件中的类名进行的插拔式的设置,一般这种设置都放在一个文件中:
app.config.from_object("python类或类的路径") app.config.from_object('pro_flask.settings.TestingConfig')
settings
class Config(object): DEBUG = False TESTING = False DATABASE_URI = 'sqlite://:memory:' class ProductionConfig(Config): DATABASE_URI = 'mysql://user@localhost/foo' class DevelopmentConfig(Config): DEBUG = True class TestingConfig(Config): TESTING = True
配置的元素:
{ '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, }
五。路由系统。
路由一般是以装饰器的方式放到需要进行修饰的视图函数上。
@app.route('/login',methods=['POST',"GET"],endpoint="sb") def login(): return "login"
在route中,其中的是一个decorator运行的是add_url_rule():
rule是一个路由,代表网页访问它所使用的路由。
endpoint是视图函数起的别名。
f 代表的是传入的视图函数。
**options代表其他参数。
1.add_url_rule
这个函数中会具体实现视图函数,返回值,并弹出methons,判断它的请求方式:
endpoint代表的是在视图函数中,通过url_for反向解析出的路由。也就是取别名,但是每个别名不能相同。#add_url_rule 源码中,
endpoint如果为空,endpoint = _endpoint_from_view_func(view_func),最终取view_func.__name__(函数名)。
app的写法还有以下这种:
app.add_url_rule('/login/<string:nid>',view_func=login,endpoint="sb",methods=['POST',"GET"])
2.路由的传参:
在rule中,可以通过以下方式传入参数,传入的参数会变成对应的类型:
app.add_url_rule('/login/<string:nid>',view_func=login,endpoint="sb",methods=['POST',"GET"])
转换器还有以下类型:
DEFAULT_CONVERTERS = { 'default': UnicodeConverter, 'string': UnicodeConverter, 'any': AnyConverter, 'path': PathConverter, 'int': IntegerConverter, 'float': FloatConverter, 'uuid': UUIDConverter, }
六。cbv的分析
在调用cbv的视图函数的时候,基本形式如下:
class loginview(views.View): # def dispatch_request(self): def dispatch_request(self,*args,**kwargs): print('666') print(args) print(kwargs) return '111' app.add_url_rule('/login',view_func=loginview.as_view(name='login'))
每个视图函数中都需要走as_view函数,如果没有name参数,所有的视图类函数都将以view命名,难以区分,所以这里的name也相当于endpoint。
decorators
这个参数代表的是装饰器,可以将齐总的装饰器都装饰到view函数中。
如果没有decorators,则进行以下步骤:
将,methods传给类对象,将本类定义到view_class,最后给view执行。
执行的结果还是运行本类中的dispatch_request,这个函数只有在自定义的类中定义。
七。cbv分发url类型。
如何将flask中的cbv像django中的一样,可以针对不同的请求方式执行对应的函数。
首先lei继承自MethodView:
通过全局的配置request中读取获取数据的方法,再从本类中反射,执行该语句。:
class loginview(views.MethodView): def get(self): dict1 = { 'name':'lzx', 'age':'10', 'add':'shanghai' } return render_template('login.html',name='lzx',name_dict=dict1) def post(self): dict1 = { 'name':'lzx' } return render_template('login.html',name='lzx',name_dict=dict1)
这时候就不能写dispatch_request函数了。