爲了避免與現行項目想衝突,一般狀況下會引入一個虛擬環境,將Flask安裝在虛擬環境下,虛擬環境用virtualenvhtml
使用Virtualenv建立虛擬環境前端
將Flask安裝在該虛擬環境裏python
或者不配置直接web
pip install flask
#Flask依賴一個實現wsgi協議的模塊:werkzeug from werkzeug.wrappers import Request, Response @Request.application def hello(request): return Response('Hello World!') if __name__ == '__main__': from werkzeug.serving import run_simple run_simple('localhost', 4000, hello)
flask依賴於wsgi,實現wsgi模塊,wsgiref,werkzeug,uwsgi正則表達式
from flask import Flask # 1 建立一個Flask實例 app = Flask(__name__) @app.route('/') # 路由系統生成,視圖對應url def first_flask(): # 視圖函數 return 'Hello World' if __name__ == '__main__': app.run() # 啓用socket
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 # 主模塊所在的目錄的絕對路徑,默認項目目錄
更改配置文件django
app.config.from_object('settings.Base') # 更改配置文件
經過路徑,找到類並獲取類中的靜態字段json
配置文件flask
@app.route('url地址',methods=['POST',"GET"],endpoint='別名',defaults={'nid':1},strict_slashes=True,redirect_to='/index') endpoint:反向生成url,默認是函數名 endpoint= 至關於django中的name url_for 至關於 reverse 不定義默認是函數名 defaults:默認參數 strict_slashes:True 嚴格要求訪問的方式, redirect_to='url':301重定向:永久重定向
接收字符串類型後端
from flask import Flask app=Flask(__name__) @app.route('/<name>') #設置url傳參數 def first_flask(name): #視圖必須有對應接收參數 print(name) return 'Hello World' #response if __name__ == '__main__': app.run()
接收int,float,接收path連接類型
# int類型 @app.route('/<int:age>/') # float類型 @app.route('/<float:salary>/') # path類型 @app.route('/<path:url>/') def first(url): # 視圖必需要對應接收參數 pass
指定容許的請求方法
@app.route('/<path:url>/',methods=['get']) #只容許get請求
經過別名反向生成url
from flask import Flask,url_for app=Flask(__name__) @app.route('/<path:url>',endpoint='name1') #設置別名 def first_flask(url): print(url_for('name1',url=url)) #若是設置了url參數,url_for(別名,加參數) return 'Hello World' if __name__ == '__main__': app.run()
from flask import Flask, views, url_for from werkzeug.routing import BaseConverter app = Flask(import_name=__name__) class RegexConverter(BaseConverter): """ 自定義URL匹配正則表達式 """ def __init__(self, map, regex): super(RegexConverter, self).__init__(map) self.regex = regex def to_python(self, value): """ 路由匹配時,匹配成功後傳遞給視圖函數中參數的值 :param value: :return: """ return int(value) def to_url(self, value): """ 使用url_for反向生成URL時,傳遞的參數通過該方法處理,返回的值用於生成URL中的參數 :param value: :return: """ val = super(RegexConverter, self).to_url(value) return val # 添加到flask中 app.url_map.converters['regex'] = RegexConverter @app.route('/index/<regex("\d+"):nid>') def index(nid): print(url_for('index', nid='888')) return 'Index' if __name__ == '__main__': app.run()
FBV
from flask import Flask,render_template app = Flask(__name__) # 導入配置 app.config.from_object('settings.類名') @app.route('/') def index(): return render_template('index.html') if __name__ == '__main__': app.run()
CBV (不經常使用)
# 1.導入views from flask import views # 寫一個類,與django中相似 class User(views.methodView): methods = ['GET'] decorators = ['裝飾器'] def dispatch_request(self,*args,**kwargs): pass def get(self): self.dispatch_request() pass def post(self): pass # 加入app中 app.add_url_rule('/user/', view_func=User.as_view(name='endpoint'))
request.form #存放form表單中的序列化數據 request.args # 存放url裏面的序列化數據 request.values.to_dict() # 存放url和from中的全部數據 request.method # 存放請求方式 request.path # 路由地址 request.url 全部的url:所有地址 request.host 主機位 127.0.0.1:5000 request.host_url 將主機位轉換成url http://127.0.0.1:5000/ request.data 查看傳過來全部解析不了的內容 request.json 查看前端傳過來的json文件 request.headers 查看全部的請求頭 file = request.files 前端傳過來的文件 file.filename 返回文件名稱 file.save() :保存文件
return '字符竄' return render_template() # 返回一個頁面 return redirect() # 重定向 return jsonify # 返回json數據,返回標準的json格式字符串 content-type: application/json
{{ }} 引用變量 非邏輯代碼時使用 {% %} 邏輯代碼使用 -基本數據類型,能夠執行python語法,如dict.get(),list[11] -傳入函數 django,能夠執行 flask,不自動執行 -全局定義 @app.template_global() @app.template_filter() -定義模板 {% extends %} 引入模板 {% include %} 引入一小部分 -宏定義 {% macro ccc(name,type='text',value='') %} <input type="{{ type }}" name={{ name }} value={{ value }}> <input type="button" value="提交"> {% endmacro %} {{ ccc('name') }} 運行 -安全 -前端 {{ll|safe}} -後端 Markup('字符串')
# 1導入session from flask import session # 2須要對其進行加鹽,也能夠在配置文件中對其加鹽 app.secret_key = 'alfkjs' # 3存session session['key'] = value # 4取值 session.get('key', None)
閃現,在session中存儲一個數據,讀取時經過pop將數據移出,
flash('內容', category= 'ok') # 第一個存的內容 # category 是別名,至關於分lei get_flashed_messages() # 取全部 # 獲取flash中的值, # get_flashed_messages()中的參數: with_categories=True # True表示返回一個元祖 category_filter='ok' #取出別名爲ok的全部參數,放在一個列表中 # 若是想將列表發送到前段,須要導入jsonify
應用場景
假設在A頁面作個操做,但該操做失敗了,要跳轉到B頁面並顯示這些錯誤信息
from flask import Flask,flash,get_flashed_messages,request,redirect app = Flask(__name__) app.debug = True app.secret_key="1234" @app.route("/index") def index(): # get請求用request.args.get, v是接受參數的變量 # 瀏覽器請求: val = request.args.get('v') if val =="body": return "hello World, guys" # 若是請求參數不是body,則跳轉到錯誤頁面,須要將錯誤信息flash,也就是設置錯誤值到某個地方 # A.flash不分類,直接設置值 flash("前端輸入參數錯誤") # B.flash還能夠對錯誤信息,進行分類 flash("前端輸入參數錯誤", category="x1") return redirect("/error") @app.route("/error") def error(): ''' 顯示錯誤信息 ''' # 跳轉到error頁面後,請求時獲取錯誤信息 # A.flash沒有分類時 # data = get_flashed_messages() # 獲取的就是flash的值 # B. 對於有分類的,取值時能夠經過 category_filter 根據分類取錯誤信息 data = get_flashed_messages(category_filter=['x1']) # 可能有不少的錯誤信息,也能夠按照索引的方式取出錯誤值 if data: msg = data[0] else: msg = "..." return "錯誤信息:%s" %(msg) if __name__=="__main__": app.run()from flask import Flask,flash,get_flashed_messages,request,redirect app = Flask(__name__) app.debug = True app.secret_key="1234" @app.route("/index") def index(): # get請求用request.args.get, v是接受參數的變量 # 瀏覽器請求: val = request.args.get('v') if val =="body": return "hello World, guys" # 若是請求參數不是body,則跳轉到錯誤頁面,須要將錯誤信息flash,也就是設置錯誤值到某個地方 # A.flash不分類,直接設置值 flash("前端輸入參數錯誤") # B.flash還能夠對錯誤信息,進行分類 flash("前端輸入參數錯誤", category="x1") return redirect("/error") @app.route("/error") def error(): ''' 顯示錯誤信息 ''' # 跳轉到error頁面後,請求時獲取錯誤信息 # A.flash沒有分類時 # data = get_flashed_messages() # 獲取的就是flash的值 # B. 對於有分類的,取值時能夠經過 category_filter 根據分類取錯誤信息 data = get_flashed_messages(category_filter=['x1']) # 可能有不少的錯誤信息,也能夠按照索引的方式取出錯誤值 if data: msg = data[0] else: msg = "..." return "錯誤信息:%s" %(msg) if __name__=="__main__": app.run()
請求 執行前會執行一個wsgi_app,因此這裏就是重寫這個方法
from flask import Flask app = Flask(__name__) @app.route("/login", methods=['GET', 'POST']) def index(): pass class Md(object): def __init__(self, old_wsgi_app): self.old_wsgi_app = old_wsgi_app def __call__(self, environ, start_response): print("開始以前") ret = self.old_wsgi_app(environ, start_response) print("結束以後") return ret if __name__ =="__main__": app.wsgi_app = Md(app.wsgi_app) # 至關於把wsgi_app給更新了 app.run()
藍圖的做用,就是將功能和主服務分開.
簡單理解就是用藍圖實例化一個對象,而後由這個對象寫一個函數,再加入flask中
使用藍圖的目標:
\1. 構造程序目錄
\2. 自定義程序目錄
批量處理url
定製模板路徑和靜態文件路徑
請求擴展:
- 能夠針對app, 即所有程序都生效
- 也能夠針對單個的藍圖,即只有在執行該藍圖時,請求擴展才會生效
簡單實例:
目錄結構
s_view.py中內容
from flask import Blueprint # 導入 Flask 中的藍圖 Blueprint 模塊 sv = Blueprint("sv", __name__) # 實例化一個藍圖(Blueprint)對象 @sv.route("/svlist") # 這裏添加路由和視圖函數的時候與在Flask對象中添加是同樣的 def view_list(): return "svlist_view_list"
manager.py中的內容
from flask import Flask # 導入此前寫好的藍圖模塊 from student_view import s_view app = Flask(__name__) # type:Flask # 在Flask對象中註冊藍圖模塊中的藍圖對象 s_view 中的 sv app.register_blueprint(s_view.sv) app.run("0.0.0.0",5000) # 如今Flask對象中並無寫任何的路由和視圖函數
而後開啓服務,就能夠訪問了http://127.0.0.1:5000/svlist
詳情:請查看博客: https://www.cnblogs.com/95lyj/p/9509229.html
@app.template_global() 全局函數 @app.template_filter() 相似標籤 @app.before_request 相似於process_request:沒有參數 順序:從上到下 @app.after_request 相似於process_response:必須有參數,並返回 順序:從下到上:即便在第一個就返回,也會所有執行一遍 @app.before_first_request 只有第一次執行 @app.teardown_request 在有異常發生時觸發 @app.errorhandler(404) 沒找到頁面走這個之下的函數,有一個參數
@app.before_request def process_request(*args, **kwargs): # 驗證表示,任何地址請求都會先執行before_request,因此登陸驗證就能夠在before_request裏作用戶認證功能了 print("其餘請求以前就執行了process_request") # 4.訪問/login的時候尚未登陸,就會一直重定向到登陸頁,因此就要設置個白名單,若是請求地址是/login,就返回None if request.path == "/login": return None # 1.登陸驗證功能 user = session.get('user_info') # 2.若是登陸信息正常,什麼都不作,程序繼續其餘執行 if user: return None # 3.若是登陸驗證不經過,就重定向到登陸頁面 return redirect("/login")
在請求進入視圖函數以前執行,與他做用相同的@app.before_first_request也是,不一樣點是這個只執行一次,而after_request能夠執行屢次,按照順序執行
@app.after_request def foot_log(environ): if request.path != "/login": print("有客人訪問了",request.path) return environ
注意:
可是要注意,多個請求擴展的執行順序是有差異的: 對於before_request,是按照寫的代碼的順序從上到下的順序正序執行的 對於after_request, 是按照寫的代碼的順序從下到上的順序倒序執行的 若是before_request return了(即程序被攔截了),其餘before_request就不執行了,可是全部的after_request都會繼續執行
實例
from flask import Flask,render_template,request,redirect,session,url_for app = Flask(__name__) app.debug = True app.secret_key = 'siuljskdjfs' @app.before_request def process_request1(*args,**kwargs): print('process_request1 進來了') return "攔截" @app.before_request def process_request2(*args,**kwargs): print('process_request2 進來了') @app.after_request def process_response1(response): print('process_response1 走了') # after_request 必須返回 response return response @app.after_request def process_response2(response): print('process_response2 走了') return response # 視圖函數 @app.route('/index',methods=['GET']) def index(): print('index函數') return "Index" if __name__ == '__main__': app.run()
執行結果:
from flask import Flask,render_template,request,redirect,session,url_for app = Flask(__name__) app.debug = True app.secret_key = 'siuljskdjfs' # 常常會出現url不存在的狀況,通常會有錯誤信息 # 而這個錯誤信息也是能夠進行定製的,根據錯誤碼定製錯誤信息方法以下: @app.errorhandler(404) def error_404(arg): return "404錯誤了" # 視圖函數 @app.route('/index',methods=['GET']) def index(): print('index函數') return "Index" if __name__ == '__main__': app.run()
from flask import Flask,request app = Flask(__name__) app.debug = True # 這就是基於請求擴展的 定製模板方法 # 相對於在模板裏定製了一個函數 @app.template_global() def sb(a1, a2): return a1 + a2 if __name__ == '__main__': app.run() #在HTML裏調用的方式以下: {{sb(1,2)}}
from flask import Flask,request app = Flask(__name__) app.debug = True # 這就是基於請求擴展的 定製模板方法 @app.template_filter() def db(a1, a2, a3): return a1 + a2 + a3 if __name__ == '__main__': app.run() #在HTML裏調用的方式以下: {{ 1|db(2,3)} # 參數 a1 = 1,是第一個參數; a2=2 是第二個參數; a3=3 是第三個參數
應用場景:數據庫的鏈接,初始化操做
from flask import Flask,request app = Flask(__name__) app.debug = True # 內部其實就有個判斷,初始值是FALSE,第一次執行後將值改變爲True,之後判斷後就不執行了 @app.before_first_request def before_first_request2(): print('before_first_request2') if __name__ == '__main__': app.run()