Flask框架-基礎

1、簡介

輕量級的框架,很是快速的就能把程序搭建起來css

Flask是一個基於Python開發而且依賴jinja2模板Werkzeug WSGI服務的一個微型框架,對於Werkzeug本質是Socket服務端,其用於接收http請求並對請求進行預處理,而後觸發Flask框架,開發人員基於Flask框架提供的功能對請求進行相應的處理,並返回給用戶,若是要返回給用戶複雜的內容時,須要藉助jinja2模板來實現對模板的處理,即:將模板和數據進行渲染,將渲染後的字符串返回給用戶瀏覽器。html

「微」(micro) 並不表示你須要把整個 Web 應用塞進單個 Python 文件(雖然確實能夠 ),也不意味着 Flask 在功能上有所欠缺。微框架中的「微」意味着 Flask 旨在保持核心簡單而易於擴展。Flask 不會替你作出太多決策——好比使用何種數據庫。而那些 Flask 所選擇的——好比使用何種模板引擎——則很容易替換。除此以外的一切都由可由你掌握。如此,Flask 能夠與您珠聯璧合。前端

默認狀況下,Flask 不包含數據庫抽象層、表單驗證,或是其它任何已有多種庫能夠勝任的功能。然而,Flask 支持用擴展來給應用添加這些功能,如同是 Flask 自己實現的同樣。衆多的擴展提供了數據庫集成、表單驗證、上傳處理、各類各樣的開放認證技術等功能。Flask 也許是「微小」的,但它已準備好在需求繁雜的生產環境中投入使用。python

- 和django的比較
    django:無socket,依賴第三方模塊wsgi,中間件,路由系統(CBV,FBV),視圖函數,ORM。cookie,session,Admin,Form,緩存,信號,序列化。。
      缺點:全部資源所有加載,形成必定資源的浪費
Flask:無socket,中間件(擴展),路由系統,視圖(CBV)、第三方模塊(依賴jinja2),cookie,自帶組件session弱爆了
      缺點:flask全部組件大部分都來自第三方,穩定性支持相對差些

- tornodo 龍捲風
  異步IO非阻塞,原生websocket ==原生支持socket,實現併發,其它兩大框架都須要第三方
  裏面組件太少,第三方支持的組件也太少

2、建立基礎Flask應用

1. 安裝程序員

pip3 install  flask

2. 建立項目web

(1)方法一可經過pycharm直接建立,python會自動建立,自動下載flask【選擇好解釋器】docker

(2)方法二,手動建立數據庫

  a、建立一個project,選好解釋器,能夠選擇建立好的虛擬環境django

  b、建立一個py文件,如app.pyjson

  c、導入Flask模塊,建立flask實例化,按其規則配好路由及寫好視圖,而後經過對象調用run方法便可啓動flask應用  

from flask import Flask

# 實例化
app = Flask(__name__)   # __name__ 當前對象,讓解釋器知道文件在那裏

# 路由
@app.route("/")
def index():
    return "hello, welcome to flask……"


if __name__ == '__main__':
    app.run(debug=True)        # 默認不支持修改內容自動更新網頁內容,加上debug後能夠自動重啓服務器,有錯誤會報錯誤頁,想快些,能夠ctrl+s來保存,快速重啓服務

3. 建立靜態文件目錄,在項目下建立一個名子必須是static的目錄,全部的圖片等靜態文件都放在裏面

4. 建立模板存放目錄,在項目下建立一個名字必須是templates的目錄,全部的模板即html文件都放在裏面

3、flask路由初始

@app.route('/', methods=['get', 'POST'])   # 以裝飾器的形式


# 寫post,必須先寫get,否則仍是405,默認支持get,若是隻是get請求能夠不指定methods

#若是發post請求時,爲指定請求方法,則會405沒有權限之報錯

4、Response三劍客及發送文件&json數據

flask               django

return 字符串          HttpResponse 返回字符串

render_template('index.html')   render()    返回模板替換後的字符串

redirect()            redirect()             重定向

from flask import Flask
from flask import request  # django裏全部的request是當參數傳,flask不是這樣,他是將請求的數據放在request的一個容器裏
from flask import redirect, render_template


app = Flask(__name__)


@app.route('/login')
def sign_in():
    return render_template('login.html')  # render


@app.route('/home', methods=['GET', 'POST'])  # 寫post,必須先寫get,否則前端報錯405表示訪問頁面沒有權限,默認支持get,若是隻是get請求能夠不指定methods
def home():
    username = request.form.get('username', "")
    password = request.form.get('password', "")
    if username == "python" and password == "make_money":
        return redirect('/index')  # redirect
    else:
        return "哪涼快,那呆着去 ……"


@app.route('/index')
def index():
    return '歡迎來到北京開始程序員之旅……'  # HttpResponse

比django多提供了兩個方法:

from flask import send_file  # 打開文件,並返回給瀏覽器
from flask import jsonify  # 將信息序列化返回給瀏覽器,並在響應頭中conten-type設置爲application/json

@app.route('/files')
def file():
    """發送文件"""
    return send_file('media/docker.mp4')  # 發送文件,圖片,視頻,音頻等,  視頻顯示不出來?????
    # return send_file('My_Flask.py')  #


@app.route('/text')
def text():
    """發送序列化格式數據"""
    dic = {"name": 'xxx'}
    # return dic   # 前端沒法接收,必須是str,tuple等,序列化後前端接到的也仍是文本
    return jsonify(dic, )

5、flask中的resquest

django中的request從請求封裝後一直當參數傳遞,而flask中request是一個內存空間,容器,它存放了全部的請求數據,須要導入

from flask import request  # django裏全部的request是當參數傳,flask不是這樣,他是將請求的數據放在request的一個容器裏
   print(request)  # <Request 'http://127.0.0.1:5000/request' [POST]>
   # from 表單,使用www-urlencoded的content-type
  # from 傳文件須要定義
<form action="/request?wife='路人甲'" method="post" enctype="multipart/form-data">
    print(request.form)  # ImmutableMultiDict([('username', 'xiuwensun@163.com'), ('password', '333'), ('filename', '')])
    print(request.args)  # url的參數
    print(request.values)  # form數據和url參數     

        request.values 存放from表單序列化數據和url後的參數
        request.values.to_dict() 轉成字典,但若是url裏的參數key和form中重名,url會覆蓋form  

    print(request.json)  # 發送是json數據時,數據從這裏獲取,而且反序列化
    print(request.data)  # 發送類型非content-type能識別的

    print(request.method)  # 請求方法
    print(request.path)  # 路由路勁
    print(request.url)  # url全部的內容,包括參數
    print(request.full_path)  # /request?wife=%27%E8%B7%AF%E4%BA%BA%E7%94%B2%27
    print(request.host)  # host主機或域名
    print(request.host_url)  # 主機名變成url
    print(request.cookies)  # 發送過來cookies的內容
    print(request.content_type)
    print(request.headers.items())  # 全部的請求頭信息,是個生成器
   print(request.files.get('file_name')) # 獲取前端上傳過來的文件,但不會保存,須要save一下
   ret = request.files.get('file_name')
   ret.save('path/自定義文件名.png'),
   也能夠保存爲原來的名字:獲取原文件名ret.filename
   即 ret.save(ret.filename)

6、flask中的session組件

from flask import session

app = Flask(__name__)

app.secret_key = "本身設定的字符串"    # 此字符串不能隨意更改,否則全部的session失效,須要從新申請


# 設置session,必須先設置secret_key       爲用戶設置session都是登陸認證成功後才設置的
session['key']  = ‘x'x'x'x'x’ 


# 獲取session

session.get('key')     # 知識點回顧,字典獲取兩種方式一種中括號,一種get,沒值時前面報錯keyerror,後面返回空,後面的也能夠設置默認值

flask中的session產生是由設置的secret_key 和設置的session值進行一個加密運算,從而獲得一個字符串,被序列化後,而後將其發給瀏覽器,保存在本地cookie中!!!

它沒有將session保存在服務器端,django是按傳統的同樣放在服務器端。

注意點:

7、jinja2模板語法

{{變量}}    引用變量,非邏輯代碼時使用

{%%}   邏輯代碼使用
# 邏輯判斷及循環使用方法都同django

{% if session %}

{% endif %}

{% for foo in session %}

{% endfor %}

  1.   模板傳參取值

flask中傳參給模板,發送的是一個單純的字典時,key可隨意定,在模板中引用,可點,可按字典兩種方法取值

----視圖
@app.route('/news') def news(): return render_template('jinja2.html', stu=STUDENT)
STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}
----html文件
<body>
{{ stu }}
<table>
    <thead>
        <tr>
            <th>名字</th>
            <th>年齡</th>
            <th>gender</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>{{ stu.0.name }}</td>
            <td>{{ stu.0.get('age') }}</td>
            <td>{{ stu.0['gender']}}</td>
        </tr>
    </tbody>
</table>
</body>

效果圖:

  2. if和for邏輯中取值

後端將字典放在列表中傳給前端,前端接到時一個列表中包着字典,取值同傳一個單純的字典同樣,能夠經過點,get,中括號取值

---view
@app.route('/news')
def news():
    return render_template('jinja2.html',  stu_list=STUDENT_LIST)


STUDENT_LIST = [
{'name': 'Old', 'age': 38, 'gender': '中'},
{'name': 'Boy', 'age': 73, 'gender': '男'},
{'name': 'EDU', 'age': 84, 'gender': '女'}
]
 
----html

<table>
    <thead>
    <tr>
        <th>名字</th>
        <th>年齡</th>
        <th>gender</th>
    </tr>
    </thead>
    <tbody>
    {% for dic in stu_list %}
        <tr>
            <td>{{ dic.name }}</td>
            <td>{{ dic.get('age') }}</td>
            <td>{{ dic['gender'] }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

  3. 當字典裏套字典傳給前端時,經過點取值報錯,只能經過另兩種,但在前端仍是能夠用keys(),values(),items() 方法

注意:flask中前端模板使用方法,須要帶括號,與django不同

STUDENT_DICT = {
    1: {'name': 'Old', 'age': 38, 'gender': '中'},
    2: {'name': 'Boy', 'age': 73, 'gender': '男'},
    3: {'name': 'EDU', 'age': 84, 'gender': '女'},
}

@app.route('/news')
def news():
    return render_template('jinja2.html',  stu_dict =STUDENT_DICT )
view
<table>
    <thead>
    <tr>
        <th>名字</th>
        <th>年齡</th>
        <th>gender</th>
    </tr>
    </thead>
    <tbody>
    {% for key in stu_dict %}
        <tr>
            <td>{{ stu_dict[key].name }}</td>
            <td>{{ stu_dict.get(key).get('age') }}</td>
            {% if stu_dict[key].gender == '中' %}
                <td>非人類</td>
            {% else %}
                <td>{{ stu_dict[key].gender }}</td>
            {% endif %}
        </tr>
    {% endfor %}
    </tbody>
</table>
html文件

  4. 繼承

母版:同django同樣,定義一個html如bash.html,引用{%   extends  'bash.html'   %}

塊: 同django  

組件: 同django

在模板中應用
{% extends 'bash.html' %}
{% block my_css %} 3333 {% endblock %}
{% include '4444.html' %}

返回標籤

前端: 經過管道符   value|safe

後端: Markup(標籤)

flask後臺傳標籤,由於防止xss攻擊,因此在前端渲染會是字符串

須要經過markup一下,同django中的safe

----後端返回安全標籤方法
from flask import Markup @app.route('/filter') def filters(): a = '
<a href="http://www.baidu.com">百度</a>' a = Markup(a) # 經過該方法告訴瀏覽器這是一個安全的標籤 return render_template('3333.html', a=a)

注: 0.9 之前的版本,在模板中應用不存在的變量報錯,後面的不報錯!!!

 8、擴展:

  一、 flask中經過手寫裝飾器聯合session如何驗證用戶登陸狀態?

from flask import Flask
from flask import session
from flask import render_template, redirect, request
from functools import wraps
"""
需求:訪問某些頁面須要用戶登陸後才能查看
方案:經過裝飾器聯合session校驗用戶登陸狀態
邏輯:
一、用戶登陸認證後,爲用戶建立惟一sessionid保存用戶信息,響應時傳給瀏覽器保存在本地cookie中,下次訪問時自動帶上session
二、在須要驗證的視圖上加上裝飾器,用戶請求路由匹配視圖後,會先走裝飾器
三、在裝飾器中,獲取用戶預訪問頁面url,保存下來next_url=request.full_path,以備登陸後自動跳轉到該頁面
   獲取用戶的攜帶的session,若是攜帶了就表示用戶處於登陸狀態
   若是未攜帶就表示未登陸,經過重定向讓用戶去登陸。
   此時爲了可以登陸後跳轉用戶需求頁面,進行url拼接,如:"/login?nexturl={}".format(next_url)
四、用戶登陸認證後,從訪問url中獲取nexturl,而後跳轉到nexturl,若是用戶是直接登陸的,就自動跳轉到主頁   
"""
app = Flask(__name__)

app.secret_key = "first_goal"  # 隨機字符串


def check_login(f):
    @wraps(f)  # 裝飾後print(f.__name__)時打印的是功能函數名而不是inner
    def inner(*args, **kwargs):
        next_url = request.full_path  # 不含主機位
        if session.get('u_info', ""):
            ret = f(*args, **kwargs)
            return ret
        return redirect('/login?next_url={}'.format(next_url))

    return inner


@app.route('/login', methods=['get', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form.get('username', "")
        password = request.form.get('password', "")
        if username == "python" and password == "123456":
            next_url = request.args.get('next_url', '/')
            session['u_info'] = username
            return redirect(next_url, )
    return render_template('login.html')


@app.route('/', methods=['get'])
def index():
    return "歡迎光臨……"


@app.route('/news')
@check_login
def news():
    return render_template('jinja2.html', stu=STUDENT, stu_list=STUDENT_LIST, stu_dict=STUDENT_DICT)

注意:裝飾器必須是最下面的一個被裝飾的,否則裝飾器失效 

上面的缺陷是,若是須要裝飾的視圖過多,就比較麻煩,還有就是,若是對多個視圖裝飾後,若是在inner函數上不進行@warp(func_name)的話,flask啓動時會進行報錯,以下圖  

 出現上面的報錯緣由是:

視圖建立,未指定endpoint時,在route初始化時,將endpoint的值設置爲視圖函數的名字

因裝飾器的緣由,被裝飾的函數,函數名變了,變成了inner,若是多個視圖被同一個裝飾器裝飾,就會致使全部的視圖函數名都成inner了,這就致使endpoint名都同樣了,

而endpoit又能夠做爲視圖的反向解析,這時就會致使沒法找到對應的視圖,故endpoint不能同樣,從而在被同一個裝飾器裝飾,endpoint就須要賦值才能解決上面的報錯。

9、Flask的參數及對app的配置

Flask 是一個很是靈活且短小精幹的web框架 , 那麼靈活性從什麼地方體現呢?

有一個神奇的東西叫 Flask配置 , 這個東西怎麼用呢? 它能給咱們帶來怎麼樣的方便呢?

首先展現一下:

from flask import Flask

app = Flask(__name__)  # type:Flask
app.config["DEBUG"] = True

這句 app.config["DEBUG"] = True 能夠實現的功能可刺激了

代碼只要發生改動,自動重啓Flask程序(app.run)

在控制檯打印的信息很是全面

以上兩個功能就是傳說中的 DEBUG 模式(調試模式)

Flask的配置就是在 app.config 中添加一個鍵值對,可是你存進去的鍵必須是config中應該存在的,若是再也不存在的話,它會默認無用,就這麼放着

config中有多少有用的key 呢?

{
    'DEBUG': False,  # 是否開啓Debug模式
    'TESTING': False,  # 是否開啓測試模式
    'PROPAGATE_EXCEPTIONS': None,  # 異常傳播(是否在控制檯打印LOG) 當Debug或者testing開啓後,自動爲True
    'PRESERVE_CONTEXT_ON_EXCEPTION': None,  # 一兩句話說不清楚,通常不用它
    'SECRET_KEY': None,  # 以前遇到過,在啓用Session的時候,必定要有它
    'PERMANENT_SESSION_LIFETIME': 31,  # days , Session的生命週期(天)默認31天
    'USE_X_SENDFILE': False,  # 是否棄用 x_sendfile
    'LOGGER_NAME': None,  # 日誌記錄器的名稱
    'LOGGER_HANDLER_POLICY': 'always',
    'SERVER_NAME': None,  # 服務訪問域名
    'APPLICATION_ROOT': None,  # 項目的完整路徑
    'SESSION_COOKIE_NAME': 'session',  # 在cookies中存放session加密字符串的名字
    'SESSION_COOKIE_DOMAIN': None,  # 在哪一個域名下會產生session記錄在cookies中
    'SESSION_COOKIE_PATH': None,  # cookies的路徑
    'SESSION_COOKIE_HTTPONLY': True,  # 控制 cookie 是否應被設置 httponly 的標誌,
    'SESSION_COOKIE_SECURE': False,  # 控制 cookie 是否應被設置安全標誌
    'SESSION_REFRESH_EACH_REQUEST': True,  # 這個標誌控制永久會話如何刷新
    'MAX_CONTENT_LENGTH': None,  # 若是設置爲字節數, Flask 會拒絕內容長度大於此值的請求進入,並返回一個 413 狀態碼
    'SEND_FILE_MAX_AGE_DEFAULT': 12,  # hours 默認緩存控制的最大期限
    'TRAP_BAD_REQUEST_ERRORS': False,
    # 若是這個值被設置爲 True ,Flask不會執行 HTTP 異常的錯誤處理,而是像對待其它異常同樣,
    # 經過異常棧讓它冒泡地拋出。這對於須要找出 HTTP 異常源頭的可怕調試情形是有用的。
    'TRAP_HTTP_EXCEPTIONS': False,
    # Werkzeug 處理請求中的特定數據的內部數據結構會拋出一樣也是「錯誤的請求」異常的特殊的 key errors 。
    # 一樣地,爲了保持一致,許多操做能夠顯式地拋出 BadRequest 異常。
    # 由於在調試中,你但願準確地找出異常的緣由,這個設置用於在這些情形下調試。
    # 若是這個值被設置爲 True ,你只會獲得常規的回溯。
    'EXPLAIN_TEMPLATE_LOADING': False,
    'PREFERRED_URL_SCHEME': 'http',  # 生成URL的時候若是沒有可用的 URL 模式話將使用這個值
    'JSON_AS_ASCII': True,
    # 默認狀況下 Flask 使用 ascii 編碼來序列化對象。若是這個值被設置爲 False ,
    # Flask不會將其編碼爲 ASCII,而且按原樣輸出,返回它的 unicode 字符串。
    # 好比 jsonfiy 會自動地採用 utf-8 來編碼它而後才進行傳輸。
    'JSON_SORT_KEYS': True,
    #默認狀況下 Flask 按照 JSON 對象的鍵的順序來序來序列化它。
    # 這樣作是爲了確保鍵的順序不會受到字典的哈希種子的影響,從而返回的值每次都是一致的,不會形成無用的額外 HTTP 緩存。
    # 你能夠經過修改這個配置的值來覆蓋默認的操做。但這是不被推薦的作法由於這個默認的行爲可能會給你在性能的代價上帶來改善。
    'JSONIFY_PRETTYPRINT_REGULAR': True,
    'JSONIFY_MIMETYPE': 'application/json',
    'TEMPLATES_AUTO_RELOAD': None,
}

以上這些Key,均可以被改寫,固然他們也都是有默認值存在的,若是沒有特殊狀況,不要改寫它的默認值

修改配置的方式大約是兩種

1.直接對app.config進行修改

app.config["DEBUG"] = True          # 等效app.debug=True    app.run(debug=True)

2.使用類的方式導入

首先要有一個settings.py的文件

class FlaskSetting:
    DEBUG = True
    SECRET_KEY = "DragonFire"

而後咱們在Flask的啓動文件中就能夠這麼寫

from flask import Flask
from settings import FlaskSetting

app = Flask(__name__)  # type:Flask
app.config.from_object("settings.FlaskSetting") 

這叫作類導入配置 

這是針對一個已經實例化的app進行的配置

那麼在Flask實例化的時候,傳遞的參數是什麼鬼呢?

其實能夠理解爲對Flask實例進行的初始配置,這裏面的參數是很是好理解,注意關鍵字是很是很是很是好理解

static_folder = 'static',  # 靜態文件目錄的路徑 默認當前項目中的static目錄
static_host = None,  # 遠程靜態文件所用的Host地址,默認爲空
static_url_path = None,  # 靜態文件目錄的url路徑 默認不寫是與static_folder同名,遠程靜態文件時複用
# host_matching是否開啓host主機位匹配,是要與static_host一塊兒使用,若是配置了static_host, 則必須賦值爲True
# 這裏要說明一下,@app.route("/",host="localhost:5000") 就必需要這樣寫
# host="localhost:5000" 若是主機頭不是 localhost:5000 則沒法經過當前的路由
host_matching = False,  # 若是不是特別須要的話,慎用,不然全部的route 都須要host=""的參數
subdomain_matching = False,  # 理論上來講是用來限制SERVER_NAME子域名的,可是目前尚未感受出來區別在哪裏
template_folder = 'templates'  # template模板目錄, 默認當前項目中的 templates 目錄
instance_path = None,  # 指向另外一個Flask實例的路徑
instance_relative_config = False  # 是否加載另外一個實例的配置
root_path = None  # 主模塊所在的目錄的絕對路徑,默認項目目錄

這裏面,咱們經常使用的參數有

static_folder = 'static',  # 靜態文件目錄的路徑 默認當前項目中的static目錄
static_url_path = None,  # 靜態文件目錄的url路徑 默認不寫是與static_folder同名,遠程靜態文件時複用
template_folder = 'templates'  # template模板目錄, 默認當前項目中的 templates 目錄

10、特殊裝飾器

 1. 特殊的裝飾器之自定義方法

      做用:能夠在視圖中定義函數,將函數名傳給前端模板,模板中經過{{ 函數名()}}  直接應用

@app.template_global()    # 全局能夠直接使用
def a_and_b(a,b):
    return a+b

@app.template_filter()    # 偏函數, 相似於過濾器
def abc(a,b,c):
    return a+b+c

模板中應用{{a_and_b(11,22) | abc(3,4)}} 能夠將前面的值當成後面函數的第一個參數

  二、請求前和請求後作些事,相似於django的中間件

@app.before_request      ===>   相似django的  process_request

執行時間:在執行視圖函數前

無返回值:繼續下一個before_request

有返回值:從最後一個after_request開始倒序執行

@app.after_request        ===>  相似process_response

執行時間:在視圖執行以後

必須有參數

必須有返回值:且不能爲str/int等不能調用的值

倒序執行一個個after_request        [代碼從上到下,反着執行]

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return "xxx"


@app.before_request  # 執行視圖前執行的業務
def check_login():
    print(1)



@app.before_request  # 執行視圖前執行的業務
def check_login1():
    print(2)
    return


@app.after_request  # 返回瀏覽器前執行的業務
def add_ms(response):
    print(3)
    return response


@app.after_request
def add_ms1(response):   # 參數必須有
    print(4)
    return response    # 必需要有返回值,且不能爲字符串


if __name__ == '__main__':
    app.run()

執行結果爲:

1

2

4

3

 還有一個@app.before_first_request:表示,當程序運行起來,第一個請求來的時候就只執行一次,下次再來就不會在執行了

其就是flash的本質,取一次值,就沒了,至關於pop了,但在一個函數內取和拿值還在

  三、Flash 閃存

session存在在服務端的一個字典裏面,session保存起來,取一次裏面仍是有的,直到你刪除以後纔沒有了

一、本質:flash是基於session建立的,flash支持往裏邊放值,只要你取一下就沒有了,至關於pop了一下。不只吧值取走,並且吧session裏的東西去掉

二、閃現有什麼用?

from flask import Flask,session,Session,flash,get_flashed_messages,redirect,render_template,request
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'

@app.route('/users')
def users():
    # 方式一
    # msg = request.args.get('msg','')
    # 方式二
    # msg = session.get('msg')
    # if msg:
    #     del session['msg']
    # 方式三
    v = get_flashed_messages()
    print(v)
    msg = ''
    return render_template('users.html',msg=msg)

@app.route('/useradd')
def user_add():
    # 在數據庫中添加一條數據
    # 假設添加成功,在跳轉到列表頁面時,顯示添加成功
    # 方式一
    # return redirect('/users?msg=添加成功')
    # 方式二
    # session['msg'] = '添加成功'
    # 方式三
    flash('添加成功')
    return redirect('/users')


if __name__ == '__main__':
    app.run(debug=True)

  四、自定義錯誤代碼如404,500等錯誤返回頁面

@app.errorhandler(404)
def my_error404(msg):
    msg = "頁面被吃了"
    return msg

@app.errorhandler(500)
def my_error500(msg):
    msg = "自定義錯誤信息"
    return render_template('500.html', msg=msg)

 

  1 2018年11月20日
  2 上節回顧:
  3     1.Flask 啓動
  4         from flask import Flask
  5         app = Flask(__name__)
  6         app.run()
  7     
  8     2.Flask 路由 + 視圖函數
  9         @app.route("/index",methods=["GET","POST"])
 10         def index():
 11             pass
 12     
 13     3.Response三劍客 + Flask小兒子:
 14         HttpResponese  return ""
 15         render           return render_template   模板默認目錄 templates
 16         redirect       return redirect("/index") 
 17         
 18         小兒子:
 19         send_file()        # 打開文件並返回文件內容
 20         jsonify()        # 在返回的響應頭中加入 Content-type:application/json 返回標準的json格式字符串
 21         
 22     4.Request
 23         from flask import request
 24         
 25         獲取參數(數據):
 26         request.form  # form表單中的數據
 27         request.args  # 獲取URL地址中的參數數據
 28         request.values # 獲取 form + args 中的全部數據
 29         request.json    # Content-type:application/json 將數據存放在json中
 30         request.data    # 沒法識別的Content-type b""
 31         
 32         獲取請求信息: http://127.0.0.1:5000/index
 33         request.method # 獲取請求方式 8種
 34         request.host    #獲取URL主機位 127.0.0.1:5000
 35         request.url        #獲取請求的所有地址 http://127.0.0.1:5000/index
 36         request.host_url #  http://127.0.0.1:5000 
 37         request.path    # 獲取路由地址
 38         
 39     5.Jinja2:
 40         {{}} 引用 非邏輯 執行
 41         {%%} 邏輯代碼 if for 
 42         
 43         from flask import Markup
 44         Markup 返回安全標籤字符串
 45         |safe 前端操做 返回安全標籤字符串
 46         
 47         {% macro func(a,b)%}
 48             <a href={{a}}>{{b}}</a>
 49         {% endmacro %}
 50         {{func("http://","點擊")}}
 51         
 52         支持python 及 前端Object寫法
 53         
 54     6.Session:
 55         from flask import session
 56         app.secret_key = "12345678"
 57         
 58         session["key"] = "value"
 59         
 60         將Session序列化後,返回瀏覽器Cookie,再次請求的時候帶上Session
 61     
 62     上節做業:
 63 
 64     
 65 今日內容:
 66     1.Flask中的路由:
 67         endpoint:反向URL  from falsk import url_for
 68         endpoint默認視圖函數名
 69         url_for("endpoint")
 70         
 71         methods:容許訪問該視圖函數的請求方式 可迭代對象["GET","POST"]
 72         
 73         defaults={"nid":1} #默認參數
 74         strict_slashes=True # 是否嚴格要求路由地址 "/"
 75         redirect_to="/detail" # 請求層面的重定向 301
 76         
 77         @app.route("/login/<nid>",methods=["GET","POST"],endpoint="login")
 78         動態路由參數
 79         def login(nid):
 80             pass
 81     
 82     2.Flask實例化配置:
 83         template_folder="temps" 修改默認模板路徑
 84         static_folder="statics" 靜態文件訪問目錄
 85         static_url_path="/static" # 靜態文件訪問路徑URL 
 86         默認 = "/" +static_folder 
 87     
 88     3.Flask配置:
 89         secret_key
 90         debug
 91         testing
 92         app.config.from_object #使用對象配置
 93     
 94     4.藍圖 BluePrint
 95         app01 = Blueprint("app01",__name__,
 96                   template_folder="temps",
 97                   static_folder="sta",
 98                   url_prefix="/app01")    #url_prefix 藍圖前綴       
 99         app.register_blueprint(app01.app01) # 註冊藍圖
100         
101     5.特殊裝飾器:
102         @app.template_global() # 全局函數
103         @app.template_filter() # 帶篩選的全局函數 偏函數 
104         @app.before_request # 在請求進入視圖函數以前
105         @app.after_request # 在請求返回客戶端以前
106         正常狀況 :be1 - be2 - af2 - af1
107         異常狀況 : be1 - af2 - af1 
108         
109         @app.errorheadler(404) # 更改報錯頁面
110     
111     6.Flash
112         @app.before_first_request
113         def fr():
114         
115         flash(fr) # 在Flash存儲信息
116         get_flashed_messages() # 獲取Flash中的信息 並清空
117         
118         [] - flash(fr) - [fr] - get_flashed_messages()=[fr].pop - fr() - []
119         
120 今日總結:
121     1.Flask 中的路由:
122         @app.route()
123         endpoint : 反向URL 默認是視圖函數名
124         url_for(endpoint) 獲取路由地址
125         methods : 容許進入視圖函數的請求方式、
126         /login/<nid> : 動態路由參數 def login(nid)
127         
128         redirect_to : 請求進入視圖函數以前重定向 301
129         strict_slashes True False: 是否嚴格要求路由地址 "/"
130         defaults = {"nid":1} : 默認參數
131         
132     2.Flask實例化配置:
133         static_folder  # 靜態文件存放目錄
134         static_url_path # 靜態文件訪問路徑 "/static" 默認是"/"+static_folder
135         template_folder # 模板存放目錄
136     
137     3.Flask對象配置:
138         app.config.from_object(SettingClass)
139     
140     4.藍圖 Blueprint
141         是一個不能被run的flask對象
142         from falsk import Blueprint
143         app01 = Blueprint("app01",__name__)
144             static_folder  # 靜態文件存放目錄
145             static_url_path # 靜態文件訪問路徑 "/static" 默認是"/"+static_folder
146             template_folder # 模板存放目錄
147             
148         app.register_blueprint(app01)
149     
150     5.特殊裝飾器:
151         @app.before_request # 在請求進入視圖函數以前
152         @app.after_request # 響應返回客戶端以前
153         正常狀況:be1-be2-af2-af1
154         異常狀況: be1-af2-af1
155         
156         @app.errorheadler(404) def error404(arg) # 重定義錯誤返回信息 自定義錯誤頁面
157         
158     6.Flash
159         flash("123") # 在flash中存儲數據
160         get_flashed_messages() # 將Flash中的全部數據獲取並清空
筆記
相關文章
相關標籤/搜索