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)