初識 Flask

一. Python 現階段三大主流Web框架 Django Tornado Flask 對比

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:
    優勢:大而全,組件很是全面
    缺點:太大,加載太大,浪費資源

 2、Flask 的安裝與簡單使用

pip install Flask

最簡單的Flask項目,Flask三行:

from flask import Flask
    apl = Flask(__name__)
    apl.run()

3、三種返回頁面的方式

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)

4、模版語言

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>

5、一個簡單的登陸認證

一、request 的使用

二、session的應用

  • Flask中的Session很是的奇怪,他會將你的SessionID存放在客戶端的Cookie中,使用起來也很是的奇怪
  • secret_key 其實是用來加密字符串的,若是在實例化的app中沒有 secret_key 那麼開啓session必定會拋異常的
  • cookies 中 session 存儲的是經過 secret_key 加密後的 key , 經過這個 key 從flask程序的內存中找到用戶對應的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')

注意:

  裝飾器應該放在最靠近函數的地方,由於裝飾器的執行順序是從最靠近的那個開始的,不這樣寫的話會不行該函數,詳見:多個裝飾器的執行順序

 另外一種處理登陸認證的方式,相似於Django的中間件 

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() 導入

一存放,一提取,消失 

不多應用,可是要了解有這麼個東西

相關文章
相關標籤/搜索