1.和django同样都是基于python开发的web框架 2.和django同样是同步的框架 3.依赖jinja2模板和Werkzeug WSGI服务的一个微型框架
pip3 install flask
Werkzeug是一个基于WSGI的工具包,能够做为一个Web框架的底层库,它封装好了不少Web框架的东西,好比Request,Responsehtml
from flask import Flask # 实例化生成一个FLask对象 app = Flask(__name__) # 将'/'和视图函数index绑定,并添加到路由中 @app.route('/') def index(): return 'ok' if __name__ == '__main__': # run()本质是调用了run_simple() app.run()
flask能够直接返回字符串,也能够返回html页面,也能够重定向到其余页面,也能够返回json数据python
from flask import Flask, render_template, redirect, jsonify app = Flask(__name__) @app.route('/') def index(): # 1.直接返回字符串 # return 'ok' # 2.返回html页面,可使用模板语法 # dic = {'age': 18} # return render_template("index.html", name='sxc', dic=dic) # 3.重定向页面 # return redirect('/login') # 4.返回json数据 # info = [{'name': 'sxc'}, {'name': 'zzj'}] # return jsonify(info) @app.route('/login') def login(): return 'login' if __name__ == '__main__': app.run()
# flask的配置文件 from flask import Flask app = Flask(__name__) # 第一种配置方式,只能配置两种 # app.debug = True # app.secret_key = '123' # 第二种配置,以字典的形式 # app.config['DEBUG'] = True # 第三种,以文件的形式 # app.config.from_pyfile('settings.py') # 第四种,以类的方式(推荐) app.config.from_object('settings.ProductionConfig') @app.route('/index') def index(): print(123) return 'ok' if __name__ == '__main__': app.run()
具体的配置文件web
flask中的配置文件是一个flask.config.Config对象(继承字典),默认配置为: { '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, }
装饰器的方式django
@app.route('/index/<int:nid>', methods=['POST', 'GET'], endpoint='hhh')
经过源码分析获得的新方式json
app.add_url_rule('/index/<string:nid>', methods=['GET', 'POST'], view_func=index, endpoint='hhh')
路由系统的本质flask
def decorator(f): endpoint = options.pop("endpoint", None) self.add_url_rule(rule, endpoint, f, **options) return f ''' 内部代码self.add_url_rule(rule, endpoint, f, **options) 这里的self指代的就是app,rule就是/index, f就是index函数 endpoint是为该路由取的别名,不传默认是函数名 view_func就是f就是index, endpoint必须有值,当不传的状况下,默认使用函数名,若是不使用装饰器,而且view_func也不传,那么endpoint就会没有值,那么就会报错 '''
路由中的<string:nid>是它的有名分组,前面的是指定类型,后面的是传入的参数session
CBV(源码分析)app
# CBV的控制类 from flask import Flask, views app = Flask(__name__) app.debug = True class IndexView(views.View): def dispatch_request(self): print('Index') return 'index' app.add_url_rule('/index', view_func=IndexView.as_view(name='index'), endpoint='hhh') if __name__ == '__main__': app.run() # 内部源码 @classmethod def as_view(cls, name, *class_args, **class_kwargs): def view(*args, **kwargs): self = view.view_class(*class_args, **class_kwargs) return self.dispatch_request(*args, **kwargs) view.view_class = cls # 将控制类赋值给view_class view.__name__ = name # 将name赋值给__name__ view.__doc__ = cls.__doc__ view.__module__ = cls.__module__ view.methods = cls.methods view.provide_automatic_options = cls.provide_automatic_options return view ''' 上面源码的view.__name__ = name十分重要, 由于endpoint必须有值,当不传的时候默认是函数的__name__, 若是这步不设置,那么全部控制类的endpoint就都是view了,这样会出错 因此必须提早设置view.__name__ = name,故而这个name咱们必须传入, 固然咱们传入name以后仍是能够指定endpoint '''
CBV的不一样请求方式的不一样执行函数框架
# 自定义的CBV代码 class IndexView(views.MethodView): # decorators = [,,,] # 装饰器,能够有多个 def get(self): return 'index get' def post(self): return 'index post' app.add_url_rule('/index', view_func=IndexView.as_view(name='index'), endpoint='hhh') # 源码,继承MethodView class MethodView(with_metaclass(MethodViewType, View)): def dispatch_request(self, *args, **kwargs): meth = getattr(self, request.method.lower(), None) # 若是没传默认是get方法 if meth is None and request.method == "HEAD": meth = getattr(self, "get", None) assert meth is not None, "Unimplemented method %r" % request.method # 传了就是对应的方法,即meth=get/post # 下面加括号调用以后就执行自定义函数对应的方法 return meth(*args, **kwargs)