Flask

Flask攻略

python三大框架預覽

Python Web框架分類
    功能分類:
        a:收發消息相關(socket)
        b:根據不一樣的URL執行不一樣的函數(業務邏輯相關的)
        c:實現動態網頁(字符串的替換)

    Web框架分類:
        1、本身實現b,c,使用第三方的a(Django)
        2、本身實現b,使用第三方的a,c(Flask)
        3、本身實現a\b\c(Tornado)
兩個模塊
web服務器程序 《---WSGI協議---》 web應用程序

1、wsgiref
Django開發環境使用的就是wsgiref模塊
2、jinja2(Flask)
渲染HTML頁面,其實就是實現字符串的替換
python三大框架優缺點

  Flask:

    優勢: 小而精,短小精悍,第三方組件特別多

    缺點: 組件更新速度取決於開源者 

  Tornado:

    優勢: 原生的WebSocket, 異步任務, IO非阻塞玩

    缺點: 沒有組件,Session都沒有

  Django:

   優勢: 大而全,組件很是全面

    缺點: 太大,重量級框架,加載太大,浪費資源

Flask的優點

Flask中的Werkzuge原理,__call__()
Flask的第一個Hello Flask
Flask的 HTTPresponse render_template redirect
Flask中的 request
Flask中的 Jinja2 ,Markup
Flask中的 session secret_key
Flask中的路由系統 url_for

Flask中Werkzuge原理

from werkzeug.wrappers import Response, Request
from werkzeug.serving import run_simple


# application源碼裏面 get_wsgi_headers 裏面有個__call__方法
# 能夠調用__call__ 在執行flk的時候執行call裏面的結果
@Request.application
def flk(r):
    print(r.url)
    if r.url == '/123':
        asd()
    return Response("hello")

# flk
run_simple("127.0.0.1", 5500, flk)

def asd():
    print('kermit')

asd()

Flask三劍客

# HTTPresponse: return "Hello Flask"
# render_template: return render_template("login.html") #templates
# redirect: return redirect("/login")

示例:html

# Httpresponse
@app.route("/index")
def index():
    return "Hello Flask"


# render_template
@app.route("/login")
def login():
    return render_template("login.html")


# redirect
@app.route("/")
def root_path():
    return redirect("/login")

Flask須要本身開啓:(流程以下)

from flask import Flask, render_template, redirect
app = Flask(__name__)
app.run()  # 能夠自定義ip 端口  和debug模式

Flask的request

request.method 獲取請求方式
request.form 獲取FromData數據(一般狀況下的POST請求)
request.args    獲取GET方式提交的數據
request.files    獲取file
request.url_about    獲取全部的關於URL的參數
request.values    獲取所有提交方式
to_dict    坑,覆蓋,GET覆蓋POST
request.headers    獲取頭部信息
request.cookie    獲取客戶端cookie
request.json    數據頭:application/json
request.data    在沒有任何數據頭的狀況提交的POST

Flask的模板語言

# Flask 基於 Jinja2 作了一層小的封裝,向前端傳遞數據 render_template 參數傳遞 stu = {k1:v1}

{{ stu }}
    <td>{{ stu.name }}</td>
    <td>{{ stu["age"] }}</td>
    {% if stu.get("gender") == ""  %}
        <td>男</td>
    {% else %}
        <td>{{ stu.get("gender") }}</td>
    {% endif %}
    
    
    STUDENT_LIST = [
        {'name': 'stu1', 'age': 38, 'gender': ''},
        {'name': 'stu2', 'age': 73, 'gender': ''},
        {'name': 'stu3', 'age': 84, 'gender': ''}
    ]
    
    <td>{{ stu.0.name }}</td>
    <td>{{ stu[0]["age"] }}</td>
    {% if stu[0].get("gender") == ""  %}
        <td>男</td>
    {% else %}
        <td>{{ stu.0.get("gender") }}</td>
    {% endif %}


    @apl.template_global()
    def a_b_sum(a,b):
        return a+b
    {{ a_b_sum(123,234) }}
    
    @apl.template_filter()
    def a_b_c_sum(a,b,c):
        return a+b+c
    {{ 123 | a_b_c_sum(1,2) }}

注意:安全字符串,Markup至關於模板裏面有safe前端

{{ input | safe }}
    Markup() : Markup("<input type='text' name='input_tag'>")

pycharm識別模板語言的格式:設置jinja2的語言

Session

secret_key = "" 這個是開啓session必備的參數python

form flask import session
    app.secret_key = "隨意"
    session["user"] = "xxxx"
    if session.get("user")

Jsonify

json的轉換兼容性比json模塊強web

from flask import jsonify
# import json
# Flask的jsonify是等同於json
# 區別是json的轉換兼容性比json模塊強
@flk.route('/json')
def get_json():
    res = {
        "user_id": 1,
        "username": "kermit",
        "password": "123"
    }
    # return json.dumps(res)
    return jsonify(res)

Flask路由

flk.route()

"/index"  路由地址
"/index/<nid>"   動態路由地址(視圖函數須要nid參數)
"/index/<int:nid>"   動態路由地址

"/files/<filename>"     <> 裏面的filename能夠是本地文件內的任何一個文件全名,能夠把任意存在的文件內容打印到頁面上
# 能夠把全部文件內容顯示到頁面上面
@flk.route('/files/<filename>')
def files(filename):
    return send_file(filename)

補充django

methods=["GET","POST"]   容許URL的請求方式
endpoint="index"   反向URL操做,能夠解決Inner重名的問題
redirect_to="/index2"   服務器端頁面跳轉  301永久性重定向
strict_slashes=False   可使用"/"結尾 反之不能夠
defaults={"nid":1}   視圖函數默認參數

Flask配置

settings.FlaskSettingsjson

DEBUG = True
app.config["secret_key"] = "xxxxx"
TESTING = True
{
    '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,
}
flask的整套配置項

藍圖(Blueprint)

from flask import Blueprint,render_template,redirect
reg = Blueprint("reg",__name__,template_folder="reg_temp",static_folder="regs",static_url_path="/regs")

@reg.route(
"/reg") def reg_user():   return render_template("reg_index.html")

from flask import Flask import reg_user app = Flask(__name__) app.register_blueprint(reg_user.reg) if __name__ == '__main__':   app.run("0.0.0.0", 9527, debug=True)

1.Flask實例配置
app.config.form_object("setting.FlaskSetting")
app.DEBUG = True 開啓Debug模式,該完代碼不用手動重啓
app.SECRET_KEY = "xxxxx" 開啓session必備參數flask


2.初始化配置(Flask,Blueprint)
template_folder="reg_temp",
static_folder="regs",
static_url_path="/regs"

3.藍圖Blueprint
在app實例中註冊藍圖app.register_blueprint(reg_user.reg)
實例化藍圖對象reg = Blueprint("reg",__name__,template_folder="reg_temp",static_folder="regs",static_url_path="/regs")
藍圖對象一樣與Flask對象,具有獨立模板和靜態目錄後端

from flask import Blueprint, render_template, redirect
import DATA

student_list = Blueprint('student_list', __name__, static_folder="list_static", static_url_path="/list_static")


# 藍圖實例對象必定不能與視圖函數同名
@student_list.route('/list')
def list():
    return render_template('index.html')

4.before_request after_request before_frist_request
before_request 在請求進入視圖函數以前作出的處理
after_request 在視圖函數返回給用戶以前作出的處理
before_frist_request 在第一次請求進入視圖函數以前作出的處理緩存

# 相似於Django中間件的功能
@flk.before_request  # 在請求以前
def be1():
    print('在請求進入App以前作出處理')
    # 判斷url是否是/login
    if request.path == "/login":
        print('當前訪問的頁面url是:', request.path)
        # True返回None不做任何操做往下走
        return None
    if session.get("user"):
        print('userSession存在,直接訪問頁面!')
        return None
    else:
        print('user不存在,跳轉到login頁面')
        return redirect("/login")


@flk.before_request
def be2():
    print('執行be2')


# 在請求以後
@flk.after_request
def af1(response):
    print('在此時執行了after1')
    return response


@flk.after_request
def af2(response):
    print('在此時執行了after2')
    return response


# 第一次請求前執行
@flk.before_first_request
def be_first():
    print('第一次請求')


# 報錯發送的狀態碼顯示的結果
@flk.errorhandler(404)
def error_page(arg):
    return "當前頁面不存在!"

5.errorheadler(404)
def error_page(arg)
錯誤信息頭安全

第一個Flask

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2018/08/27 17:19
# @Author  : MJay_Lee
# @File    : flask_demo_test.py
# @Contact : limengjiejj@hotmail.com


from flask import Flask # 導入Flask類

app = Flask(__name__) # 實例化Flask對象 app

@app.route("/") # app中的route裝飾器
def index(): # 視圖函數
    return "first flask app"

app.run("0.0.0.0",5000,debug=True) # 啓動Flask Web 服務

Flask三劍客

Flask中的HTTPResponse

在Flask中的HTTPResponse,在咱們看來其實就是直接返回字符串

from flask import Flask

app = Flask(__name__)

@app.route('/') # 路由
def index(): # 視圖
    return "Hello Flask" # HTTPResponse

Flask中的redirect

from flask import Flask,redirect

app = Flask(__name__)

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

@app.route('/redi') # app中的route裝飾器,用來指定視圖函數的URL地址
def redi(): # 視圖函數
    return redirect('/') # redirect 跳轉至 '/'

app.run("0.0.0.0",5500,debug=True)

Flask中的render(render_template)

from flask import Flask,redirect,render_template

app = Flask(__name__)

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

@app.route('/redi')
def redi():
    return redirect('/')


@app.route("/home") # app中route裝飾器,用來指定視圖函數的url地址
def home(): # home 視圖函數
    return render_template("home.html") # 渲染HTML模板發安徽HTML頁面

app.run("0.0.0.0",5500,debug=True)

 注意:若是要使用render_template返回渲染的模板,請在項目的主目錄中加入一個目錄templates文件夾

 

Flask中的request

每一個框架中都有處理請求或收發消息的機制(request),而每一個框架都有異同

一個form表單post的提交方式

html文件

<form action="" method="post" novalidate>
    <input type="text" name="user" id="">
    <input type="password" name="pwd" id="">
    <input type="submit" value="提交">

py文件

@app.route("/home",methods=["GET","POST"]) # app中route裝飾器,用來指定視圖函數的url地址
def home(): # home 視圖函數
    if request.method == "POST":
        print(request.method) # POST
        print(request.form) # ImmutableMultiDict([('user', 'lmj'), ('pwd', '123')])
        print(request.form['user']) # lmj
        print(request.form['pwd']) # 123
        print(list(request.form.keys())) # ['user', 'pwd']
        return "POST請求已受理"

    return render_template("home.html") # 渲染HTML模板

 methods=["GET","POST"]表明這個URL地址只容許請求的方式,是個列表

request的參數獲取

那麼request的參數獲取的幾個方式

html文件

<form action="/home?id=1&age=18" method="post" novalidate>
    <input type="text" name="user" id="">
    <input type="password" name="pwd" id="">
    <input type="submit" value="提交">

py文件

@app.route("/home",methods=["GET","POST"]) # app中route裝飾器,用來指定視圖函數的url地址
def home(): # home 視圖函數
    if request.method == "POST":
        print(request.form) # form表單中的參數

        print('request.args'.center(50,"="))
        print(list(request.args)) # url中的參數

        print('request.values'.center(50,"="))
        print(list(request.values)) # 全部參數

        print('request.values.to_dict'.center(50,"="))
        print(request.values.to_dict()) # 將參數轉爲字典

        return "POST請求已受理"
    return render_template("home.html") # 渲染HTML模板發安徽HTML頁面

結果

===================request.args===================
['id', 'age']
==================request.values==================
['id', 'age', 'pwd', 'user']
==============request.values.to_dict==============
{'user': 'lmj', 'pwd': '123', 'id': '1', 'age': '18'}

注意:

# 注意這裏的坑來啦! 坑來啦!
# 若是url和form中的Key重名的話,form中的同名的key中value會被url中的value覆蓋
# http://127.0.0.1:5500/req?id=1&user=cly
print(request.values.to_dict())  # {'user': cly'pwd': '123', 'id': '1'}

request.cookies

print(request.cookies)
"""
{
    'csrftoken': 'elPT8HW8Zw74NPSftY0suJEqbm3cOxEPl05f1oezHN61kikgqOgcuXWtiJCyhtuX', 
    'sessionid': 'cqfjxs0svrq2nqf9i4hdghdvqep6468w'
}
"""

request.headers,請求頭中的參數

print(type(request.headers)) # <class 'werkzeug.datastructures.EnvironHeaders'>
print(request.headers)
'''
Host: 127.0.0.1:5500
Connection: keep-alive
Content-Length: 16
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36
Origin: http://127.0.0.1:5500
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://127.0.0.1:5500/home
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,und;q=0.8,en;q=0.7
Cookie: csrftoken=elPT8HW8Zw74NPSftY0suJEqbm3cOxEPl05f1oezHN61kikgqOgcuXWtiJCyhtuX; sessionid=cqfjxs0svrq2nqf9i4hdghdvqep6468w
'''

request.data,若處理不了的就變成字符串存在data裏

能夠request.data,json.loads一樣能夠拿到裏面的數據

你必定要知道 request 是基於 mimetype 進行處理的

mimetype的類型 以及 字符串兒 : http://www.w3school.com.cn/media/media_mimeref.asp

若是不屬於上述類型的描述,request就會將沒法處理的參數轉爲Json存入到 data 中

request.files,文件上傳

遇到文件上傳,request.files村的就是上傳的文件,但Flask在這個文件的操做中加了封裝

html文件

<form action="" method="post" enctype="multipart/form-data" novalidate>
    <input type="file" name="file">
    <input type="submit" value="提交">
</form>

py文件

@app.route("/home",methods=["GET","POST"]) 
def home():
    if request.method == "POST":
        print(request.files) # ImmutableMultiDict([('file', <FileStorage: '待整理內容.txt' ('text/plain')>)])
        print(request.files["file"]) # <FileStorage: '待整理內容.txt' ('text/plain')>
        my_file = request.files["file"]
        my_file.save("upload_file.txt") # 保存文件,裏面能夠寫完整路徑+文件名

        return "POST請求已受理"
    return render_template("home.html")

request的路徑獲取

    # 獲取當前的url路徑
    print(request.path)# /home
    # 當前url路徑的上一級路徑
    print(request.script_root) #
    # 當前url的所有路徑
    print(request.url) # http://127.0.0.1:5000/home
    # 當前url的路徑的上一級所有路徑
    print(request.url_root ) # http://127.0.0.1:5000/

request.json

前提是你得告訴是json數據

若是在請求中寫入了 "application/json" 使用 request.json 則返回json解析數據, 不然返回 None

Flask中的jinja2和render_template

前端-普通數值

<table border="1px">
    <thead>
        <tr>
            <td>姓名</td>
            <td>年齡</td>
            <td>性別</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>{{ stu.name }}</td>
            <td>{{ stu["age"] }}</td>
            <td>{{ stu.get("gender") }}</td>
        </tr>
    </tbody>
</table>

效果

能夠看出來,字典傳入前端Jinja2 模板語言中的取值操做, 與Python中的Dict操做極爲類似,而且多了一個student.name的對象操做

前端-【列表】

<table border="1px">
    <thead>
    <tr>
        <td>姓名</td>
        <td>年齡</td>
        <td>性別</td>
    </tr>
    </thead>
    <tbody>
    {% for stu in stu_list %}
        <tr>
            <td>{{ stu.name }}</td>
            <td>{{ stu["age"] }}</td>
            <td>{{ stu.get("gender") }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

效果

前端-【字典】

<table border="1px">
    <thead>
    <tr>
        <td>姓名</td>
        <td>年齡</td>
        <td>性別</td>
    </tr>
    </thead>
    <tbody>
    {% for item in stu_dict %}
        <tr>
            <td>{{ stu_dict[item].name }}</td>
            <td>{{ stu_dict[item]["age"] }}</td>
            <td>{{ stu_dict[item].get("gender") }}</td>
        </tr>
    {% endfor %}
    </tbody>
</table>

效果

render_template中可傳遞多個關鍵字

利用 **{}字典的方式實現

py文件

@app.route("/allstudent")
def all_student():
    return render_template("all_student.html", **{"student":STUDENT ,
                           "student_list" : STUDENT_LIST,
                           "student_dict": STUDENT_DICT})

jinja2 的高階用法

後端文件

from flask import Flask
from flask import render_template
from flask import Markup  # 導入 flask 中的 Markup 模塊

app = Flask(__name__)


@app.route("/")
def index():
    tag = "<input type='text' name='user' value='DragonFire'>"
    markup_tag = Markup(tag)  # Markup幫助我們在HTML的標籤上作了一層封裝,讓Jinja2模板語言知道這是一個安全的HTML標籤
    print(markup_tag,
          type(markup_tag))  # <input type='text' name='user' value='DragonFire'> <class 'markupsafe.Markup'>
    return render_template("index.html", tag=markup_tag)


app.run("0.0.0.0", 5000, debug=True)

還有一種方式就是在前端,加上 safe

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ tag | safe}}  <!--  加上個 \  管道符,而後 safe  -->
</body>
</html>

jinja2  模板中執行函數

後端

def a_b_sum(a,b):
    return a + b


@app.route("/home",methods=["GET","POST"])
def home():
    return render_template("home.html",tag = a_b_sum)

前端

{{ tag }}
<br>
{{ tag(10,20) }}

效果

補充:定義全局函數,無需後端傳遞給前端,jinja2就能夠直接執行的函數

後端

 

@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


@app.route("/home",methods=["GET","POST"])
def home():
    return render_template("home.html")

 

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    {{ a_b_sum(99,1) }}
    <br>
    {{ 1 | a_b_c_sum(197,2) }}
</body>
</html>

jinja2 模板複用block

若是咱們前端頁面有大量重複頁面,不必每次都寫,可使用模板複用的方式複用模板

 同理於django的母版

jinja2 模板語言中的宏定義

前端

<!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>
<h2>定義宏</h2>
{% macro type_text(name,type) %}
    <input type="{{ type }}" name="{{ name }}" value="{{ name }}">
{% endmacro %}
<br>
<h2>使用宏來生成input標籤</h2>
{{ type_text("one","text") }}
{{ type_text("two","text") }}
</body>
</html>

效果:

Flask 第五篇幅

 flask-login與驗證校驗,待更新

https://www.cnblogs.com/minsons/p/8045916.html
參考筆記

Flask 的路由系統

route 裝飾器中的參數

methods,當前url地址,容許訪問的請求方式

@app.route("/index",methods=["GET","POST"]) # 當前url地址容許訪問的請求方式
def index():
    return render_template("index.html")

endpoint,反向url地址,默認爲視圖函數名(url_for)

from flask import Flask,render_template,url_for

app = Flask(__name__)

@app.route("/index",methods=["POST","GET"],endpoint="url_info") # 反向url地址,默認爲視圖函數名 (url_for)
def index():
    print(url_for("url_info")) # /index
    return render_template("index.html")

app.run("0.0.0.0",9527,debug=True)

defaults,視圖函數的參數默認值

from flask import Flask,render_template

app = Flask(__name__)

@app.route("/index",defaults={"user_list":["lmj","cly"]})
def index(user_list):
    return render_template("index.html",user_list=user_list) # 視圖函數的默認參數
app.run("0.0.0.0",9527,debug=True)

strict_slashes,url地址結尾符"/"的控制,默認爲True(結尾必須不能是"/")

from flask import Flask,render_template

app = Flask(__name__)

@app.route("/index",strict_slashes=False) # 有效訪問地址:/index 或 /index/
def index():
    return render_template("index.html")
app.run("0.0.0.0",9527,debug=True)

redirect_to,url地址重定向

from flask import Flask,render_template

app = Flask(__name__)

@app.route("/home")
def home():
    return "你已跳轉至home頁面"

@app.route("/index",redirect_to='/home')
def index():
    return render_template("index.html")


app.run("0.0.0.0",9527,debug=True)

subdomain,子域名前綴subdomain="mjlee"這樣寫就能夠獲得mjlee.dream.com

前提是app.config["SERVER_NAME"]="dream.com"

from flask import Flask,render_template

app = Flask(__name__)

app.config["SERVER_NAME"] = "dream.com"

@app.route("/index",subdomain="mjlee")
def index():
    return render_template("index.html")


app.run("0.0.0.0",9527,debug=True)

# 訪問地址爲:mjlee.dream.com/index

動態參數路由

from flask import Flask,url_for

app = Flask(__name__)


# 訪問地址 http://127.0.0.1:5500/index/9527
@app.route("/index/<int:nid>",endpoint="url_info")
def index(nid):
    print(url_for("url_info",nid=nid)) # /index/9527
    return f"success get by {nid}" # success get by 9527


app.run("0.0.0.0",5500,debug=True)

<int:nid>就是在url後定義一個參數接收

可是這種動態參數路由,在url_for的時候,必定要將動態參數名+參數值添加進去(nid=nid),不然報錯

補充:

另外還可以使用正則路由,前提是正則玩的溜

Flask 的config

 Flask的靈活體現出自其config配置,首先展現一下:

from flask import Flask

app = Flask(__name__) # type:Flask

print(app.config)
print(app.config["APPLICATION_ROOT"])


# 默認狀況下,config的28個key的詳情:
{
    'DEBUG': False,  # 是否開啓DEBUG模式
    'TESTING': False,  # 是否開啓測試模式
    'PROPAGATE_EXCEPTIONS': None,  # 異常傳播(是否在控制檯打印LOG)
    'PRESERVE_CONTEXT_ON_EXCEPTION': None, 
    'SECRET_KEY': None,  # 啓用Session的時候,必定要使用它
    'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31),  # days,Session的生命週期默認31天
    'USE_X_SENDFILE': False,  # 是否啓用 x_sendfile
    'LOGGER_NAME': '__main__',  # 日誌記錄器的名稱
    '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,  # cookie的路徑
    'SESSION_COOKIE_HTTPONLY': True,  # 控制 cookie 是否應被設置 httponly 的標誌
    'SESSION_COOKIE_SECURE': False,  # 控制 cookie 是否應被設置安全標誌
    'SESSION_REFRESH_EACH_REQUEST': True,  # 這個標誌控制永久會話如何刷新
    'MAX_CONTENT_LENGTH': None,  # 若是設置爲字節數, Flask會拒絕內容大於此值的請求進入並返回403狀態碼
    'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200),  # 12小時,默認緩存控制的最大期限
    '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
}

app.config["DEBUG"] = True

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

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

修改配置的方式:

一、直接對app.config進行修改

app.config["DEBUG"]=True

二、使用類的方式導入

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

settings.py

class FlaskSetting:
    DEBUG = True
    SECRET_KEY = "lmj"

而後在Flask的啓動文件中引用

from flask import Flask

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

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

app.run("0.0.0.0",9528)

這叫作類導入配置

以上是針對一個已經實例化的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 目錄

Flask 的藍圖

 (老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

 

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

 

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

 

(老子是寫你麻痹祖宗!兩個系統來回切換寫一篇博客真的是天坑!!!一天的工做記錄全沒了!)

相關文章
相關標籤/搜索