1.Django 主要特色是大而全,集成了不少組件,例如: Models Admin Form 等等, 無論你用獲得用不到,反正它全都有,屬於全能型框架html
2.Tornado 主要特色是原生異步非阻塞,在IO密集型應用和多任務處理上佔據絕對性的優點,屬於專一型框架前端
3.Flask 主要特色小而輕,原生組件幾乎爲0, 三方提供的組件請參考Django 很是全面,屬於短小精悍型框架django
Django 一般用於大型Web應用因爲內置組件足夠強大因此使用Django開發能夠一鼓作氣flask
Tornado 一般用於API後端應用,遊戲服務後臺,其內部實現的異步非阻塞真是穩得一批後端
Flask 一般應用於小型應用和快速構建應用,其強大的三方庫,足以支撐一個大型的Web應用安全
Django 優勢是大而全,缺點也就暴露出來了,這麼多的資源一次性所有加載,確定會形成一部分的資源浪費cookie
Tornado 優勢是異步,缺點是乾淨,連個Session都不支持session
Flask 優勢是精悍簡單app
總結:框架
Flask:
優勢:小而精,短小精悍,第三方組件特別多
缺點:組件更新速度取決於開源者,你不會
Tornado:
優勢:原生的WebSocket,異步任務,IO非阻塞
缺點:組件沒有,Session都沒有
Django:
優勢:大而全,組件很是全面
缺點:太大,加載太大,浪費資源
pip install Flask
最簡單的Flask項目,Flask三行:
from flask import Flask apl = Flask(__name__) apl.run()
from flask import Flask, render_template, redirect # 一個flask對象 app = Flask(__name__)
STUDENT_LIST = [ {'name': 'Old', 'age': 38, 'gender': '中'},
{'name': 'Boy', 'age': 73, 'gender': '男'},
{'name': 'EDU', 'age': 84, 'gender': '女'} ]# render 注意, templates文件要和當前py文件同級,否則會找不到,報一個Jinja2的異常哦 @app.route('/index') def index(): html_msg = '<h1>my html</h1>' markup_tag = Markup(html_msg) # 至關於在html頁面加上 safe ,這裏寫了,前端頁面就不用寫了 return render_template('index.html', stu=STUDENT_LIST, markup_tag=markup_tag, tag="") # HTTPResponse @app.route('/') def one_test(): return 'hello girl' # redirect @app.route('/hello') def hello(): return redirect('/index')
if __name__ == '__main__':
# debug模式運行
app.run(debug=True)
1.模版函數
二、數據安全
三、 for if 等的用法和django裏的同樣
四、模版繼承的用法也和django同樣,就不寫了
舉個栗子:
在 app.py 中
######### 在Jinja2中執行Python函數(模板中執行函數) ############ @app.template_global() # 定義全局模板函數 def a_b_sum(a, b): return a + b @app.template_filter() # 定義全局模板函數 def a_b_c_sum(a, b, c): return a + b + c def index(): html_msg = '<h1>my html</h1>' markup_tag = Markup(html_msg) # 至關於在html頁面加上 safe ,這裏寫了,前端頁面就不用寫了 return render_template('index.html', stu=STUDENT_LIST, markup_tag=markup_tag, tag="")
在index.html頁面裏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body> <!-- 在Jinja2中執行Python函數(模板中執行函數) --> {{ a_b_sum(99,1) }} <br> {{ 1 | a_b_c_sum(197,2) }} <!-- 插入 markup 處理後的html標籤 --> {{ markup_tag }} <table> <thead> <tr> {% for foo in stu[0] %} <td>{{ foo }}</td> {% endfor %} </tr> </thead> <tbody> {% for st in stu %} <tr> {% for t in st %} <td>{{ st[t] }}</td> {% endfor %} </tr> {% endfor %} </tbody> </table> </body> </html>
二、session的應用
三、裝飾器的使用及遇到的問題
四、相似Django中間件,.@app.before_request 和 @app.after_request errorheadler
先看代碼吧~
在app.py中:
from flask import Markup # 導入 flask 中的 Markup 模塊 from flask import Flask, render_template, redirect from flask import request from flask import session # 一個flask對象 app = Flask(__name__) # cookies 中 session 存儲的是經過 secret_key 加密後的 key , 經過這個 key 從flask程序的內存中找到用戶對應的session信息 app.secret_key = "LYJ" import functools # 一個認證裝飾器 def my_auth(func): @functools.wraps(func) def war(*args, **kwargs): if session.get('user'): return func() else: return redirect('/login') return war @app.route('/login', methods=['GET', 'POST']) def login(): if request.method == 'POST': print(request.form) # ImmutableMultiDict([('username', 'qwe'), ('pwd', '123')]) username = request.form['username'] # 以字典方式取值 pwd = request.form.get('pwd') print(username, pwd) # session的應用 session['user'] = username return redirect('/index') if request.method == 'GET': return render_template('login.html') # 認證,自定義裝飾器的使用 @app.route('/index2', endpoint='index2') @my_auth def index2(): return redirect('/index') #用的是示例模版的那個index @app.route('/index3', endpoint='index3') @my_auth def index3(): return redirect('/index') # AssertionError: View function mapping is overwriting an existing endpoint function: war # 由於在通過裝飾器後 func 的 __name__都變成了裝飾器的名字,因此 route 在處理時,會取到多個同樣的方法名 # 有兩種解決辦法 一、 在裝飾器中加上 裝飾器修復 @functools.wraps(func) 二、 用endpoint給傳入route的函數命名: @app.route('/index3',endpoint='index3') if __name__ == '__main__': # debug模式運行 app.run(debug=True)
若是直接加裝飾器的話,會報錯
AssertionError: View function mapping is overwriting an existing endpoint function: war
緣由:在通過裝飾器後 func 的 __name__都變成了裝飾器的名字,因此 route 在處理時,會取到多個同樣的方法名
有兩種解決辦法:
一、 在裝飾器中加上 裝飾器修復 @functools.wraps(func)
二、 用endpoint給傳入route的函數命名: @app.route('/index3',endpoint='index3')
注意:
裝飾器應該放在最靠近函數的地方,由於裝飾器的執行順序是從最靠近的那個開始的,不這樣寫的話會不行該函數,詳見:多個裝飾器的執行順序
1.@app.before_request 在請求(request)以前作出響應
from flask import Flask from flask import request from flask import redirect from flask import session app = Flask(__name__) # type:Flask app.secret_key = "DragonFire" @app.before_request def is_login(): if request.path == "/login": return None if not session.get("user"): return redirect("/login") @app.route("/login") def login(): return "Login" @app.route("/index") def index(): return "Index" @app.route("/home") def home(): return "Login" app.run("0.0.0.0", 5000)
@app.before_request 也是一個裝飾器,他所裝飾的函數,都會在請求進入視圖函數以前執行
request.path 是來讀取當前的url地址若是是 /login 就容許直接經過 return None 你能夠理解成經過放行
校驗session中是否有user 若是沒有的話,證實沒有登陸,因此絕不留情的 redirect("/login") 跳轉登陸頁面
還有一個要提的 @app.before_first_request 它與 @app.before_request 極爲類似或者說是如出一轍,只不過它只會被執行一次
2. @app.after_request 在響應(response)以前作出響應
@app.after_request
def foot_log(environ): if request.path != "/login": print("有客人訪問了",request.path) return environ
3. errorheadler(404) 定義錯誤信息
def error_page(arg) 錯誤信息頭
四、flash 導入
flash("message") get_flashed_messages() 導入
一存放,一提取,消失
不多應用,可是要了解有這麼個東西