flask
每天的內容
- flask跑起來
- 模板引擎
- flask表單
- 文件上傳郵件發送
- flask-sqlalchemy
一、web框架的簡介
M 模型 負責數據的操作
V 視圖 負責數據的展示
C 控制器 控制你的M的操作以及視圖模板的渲染
在python中叫做MVT
M 模型 負責數據的操作
V 控制你的M的操作以及視圖模板的渲染 業務邏輯的操作
T templates 模板 負責數據的展示
二、架構
BS browser-》server
CS client-》server
三、FLASK
概念: flask是一個非常小的web框架 被稱爲微型框架 只提供了一個強健的核心 其它的都是通過第三方擴展庫來實現
組成:
- 調試 路由 WSGI
- 模板引擎 jinja2 (就是由flask核心人員開發的模板引擎)
使用:
安裝 pip install flask
實例
from flask import Flask
app = Flask(__name__) #實例化flask
#路由地址 根據用戶不同的url進行處理
@app.route('/')
def index():#處理當前請求的函數
return 'Hello Flask'
if __name__ == '__main__':
app.run() #運行當前的flask
四、視圖函數
(1) 無參路由
#路由地址和視圖函數名稱 是否同名沒有關係
#http://127.0.0.1:5000/test/
@app.route('/test/') #路由地址末尾的/建議加上
def test():
return '我是測試使用的視圖函數'
(2) 帶一個參數的路由
http://127.0.0.1:5000/page/10/
@app.route('/page/<pagenum>/') #參數的語法格式 /路由名稱/<形參名>/
def page(pagenum):
return '當前的頁碼爲{}'.format(pagenum)
(3) 帶多個參數
#帶多個參數
# http://127.0.0.1:5000/arg/10/zhansgan/
@app.route('/arg/<age>/<name>/')
def getarg(age,name):
return '我叫{} 我見年{}歲了'.format(name,age)
# http://127.0.0.1:5000/arg/zhansgan_10/
@app.route('/arg/<name>_<age>/')
def getarg(age,name):
return '我叫{} 我見年{}歲了'.format(name,age)
(4) 限制參數的類型
#參數類型
# @app.route('/argtype/<arg>/')
# @app.route('/argtype/<int:arg>/') #限定參數類型爲int
# @app.route('/argtype/<float:arg>/') #限定參數類型爲float
# @app.route('/argtype/<string:arg>/') #限定參數類型爲string 默認就是字符串
@app.route('/argtype/<path:arg>/') #其實path就是string 但是path會將路由地址後面的所有的路由或者值都認爲是一個值 /不在作爲分隔符來使用
def argtype(arg):
print(type(arg))
print(arg)
return '獲取參數類型的視圖函數'
注意
- 路由地址末尾的/建議加上 因爲如果輸入的時候沒有加默認的/瀏覽器會自動幫你加上
- 形參名字寫在路由的<> 中間
- 參數默認類型都爲string
五、視圖函數的響應
(1) return 字符串進行響應
@app.route('/response/')
def res():
return '我是響應',404 #響應一個指定標準的狀態碼
(2) 通過make_response構造響應
導入:
from flask import make_response
@app.route('/make_response/')
def makeResponse():
res = make_response('我是響應的內容')
# res = make_response('我是響應的內容',404)
return res
六、重定向 redirect
作用: 從一個地址跳向另外一個地址
導入
from flask import redirect
實例
@app.route('/')
def index():#處理當前請求的函數
return 'Hello Flask'
#重定向
@app.route('/redirect/')
def redirect_index():
return redirect('/') #參數爲路由地址
return redirect('/argtype/redirect_index/') #帶參數路由地址的重定向
url_for 通過視圖函數名稱 反向構造出路由地址
導入
from flask import redirect,url_for
實例
@app.route('/redirect/')
def redirect_index():
url = url_for('test')
url = url_for('getarg',name='zhangsan',age=18) #帶多個參數
#@app.route('/arg/<name>_<age>/')
#def getarg(age,name):
return url #/test/
注意:
如果給定的視圖函數名稱不存在 則拋出異常
url_for 和 redirect 組合使用
@app.route('/redirect/')
def redirect_index():
return redirect(url_for('test'))
return redirect(url_for('getarg',name='zhangsan',age=18)) #帶多個參數
七、abort 終止
概念:
在視圖函數中處理的時候 可以使用abort拋出指定狀態碼的錯誤 下面代碼不在執行
需要拋出標準http的狀態碼
from flask import abort
實例
@app.route('/abort/')
def my_abort():
# abort(404)
# abort(500)
return '拋出狀態碼'
#捕獲500的錯誤
@app.errorhandler(500)
def server_error(e):
return '現在能看到了嗎{}'.format(e)
#捕獲404的錯誤信息
@app.errorhandler(404)
def server_error(e):
return '您訪問的頁面被外星人劫持走了!!!'
八、app.run() 參數說明
參數 | 參數說明 | 默認值 |
---|---|---|
host | 主機名 | 127.0.0.1 |
port | 端口號 | 5000 |
debug | 調試 | False |
threaded | 多線程 | False |
實例
if __name__ == '__main__':
# app.run(debug=True) #開啓調試模式
app.run(host='0.0.0.0',port=5001,debug=True,threaded=True)
十、請求 request
說明:
request是由flask框架爲我們提供好的對象 使用時 只要導入即可
用戶在請求的時候 框架會爲當前請求的用戶 創建一個request(請求的對象) 包含當前用戶請求的所有信息
導入
from flask import request
- url 用戶請求的完整的url
- base_url 去除get傳參後的url
- host_url 只有主機和端口號的url
- path 獲取請求的路由地址
- method 請求的方法
- args 獲取get傳參
- form 獲取表單傳遞過來的數據
- files 獲取文件上傳過來的數據
- headers 獲取用戶請求過來的頭信息
- cookies 獲取用戶請求過來的所有cookie
- json 獲取用戶請求過來的json數據
實例
@app.route('/request/')
def get_request():
print('用戶請求的完整的url',request.url)
print('去除get傳參後的url',request.base_url)
print('只有主機和端口號的url',request.host_url)
print('獲取請求的路由地址',request.path)
print(' 請求的方法',request.method)
print('獲取拼湊的get傳參',request.args)
print('獲取拼湊的get傳參',request.args.get('name'))
print('獲取拼湊的get傳參',request.args.get('age'))
print('獲取表單傳遞過來的數據',request.form)
print('獲取文件上傳過來的數據',request.files)
print('獲取用戶請求過來的頭信息',request.headers)
print('獲取用戶請求過來的所有cookie',request.cookies)
print('獲取用戶請求過來的json數據',request.json)
return 'request對象'
十一、會話控制 cookie和session
cookie
設置cookie
response.set_cookie(
key, #設置鍵
value,#設置值
max_age=None, #過期時間
path = '/' #當前cookie的存儲路徑
)
獲取cookie
@app.route('/get_cookie/')
def get_cookie():
print(request.cookies)
return request.cookies.get('name','default默認值')
刪除cookie
#清除cookie
@app.route('/del_cookie/')
def del_cookie():
res = make_response('清除cookie')
res.delete_cookie('name')
return res
cookie存儲值爲明文存儲 安全性低
cookie存在客戶端(瀏覽器中)
cookie默認存活時間爲 當前瀏覽結束(關閉當前的瀏覽器)
session
session的使用 需要一個secret_key 來進行加密產生加密的字符串
app.config['SECRET_KEY'] = 'secretkey'
會給cookie設置一個唯一的標識符 sessionId 服務器端會通過cookie攜帶着唯一的sessionId來區分是哪一個用戶的請求 如果客戶端的cookie被禁用了 那麼服務器端的session將無法使用 session基於cookie
設置session
#設置session
@app.route('/set_session/')
def set_session():
默認存活當前瀏覽器結束
session['username'] = '張三'
return '設置session'
設置session 及過期時間
#設置session
@app.route('/set_session/')
def set_session():
session.permanent = True #設置session持久化存儲
#設置當前session的存活時間60秒 如果當前設置失敗 那麼存活時間爲1月
app.permanent_session_lifetime = timedelta(seconds=60)
session['username'] = '張三'
return '設置session'
獲取session
#獲取session
@app.route('/get_session/')
def get_session():
return session.get('username','default默認值')
刪除session
@app.route('/del_session/')
def del_session():
#刪除 key爲username的session
session.pop('username')
#刪除所有session
# session.clear()
return '刪除session'
十二、flask-script擴展
簡介:
就是一個flask終端運行的解析器 通過不同參數 來設置flask的啓動項
安裝
sudo pip3 install flask-script
使用
from flask_script import Manager #導入終端運行的解析器
app = Flask(__name__)
manager = Manager(app)
...
if __name__ == '__main__':
manager.run()
啓動參數
-h | 主機 |
---|---|
-p | 端口號 |
-d | 調試 |
-r | 重新加載 |
-threaded | 多線程 |
python manage.py runserver -hpython manage.py runserver -h0.0.0.0 -p5000 -d -r --threaded
python manage.py runserver -d -r
十三、藍本藍圖 Blueprint
概述
當所有代碼越愛越多的時候 在manage.py中 很明顯是不合理的 我們需要將不同功能的視圖函數 存放在不同的文件中 使用我們的項目的目錄結構更加的清晰
使用
user.py 用戶的處理
from flask import Blueprint
user = Blueprint('user',__name__)
@user.route('/login/')
def login():
return '登錄'
manage.py中
from mysession import mysession
from user import user
#http://127.0.0.1:5000/login/
app.register_blueprint(user) #註冊藍本
#http://127.0.0.1:5000/user/login/
app.register_blueprint(user,url_prefix='/user') #註冊藍本並添加前綴
藍本中的重定向
@app.route('/')
def index():
# return '首頁'
return redirect('/user/login/')
return redirect(url_for('user.login')) #使用url_for反向構造出路由的時候 需要指定當前的視圖函數 是哪一個藍本對象的
十四、請求鉤子函數
在manage文件中使用
鉤子函數 | 功能描述 |
---|---|
before_first_request | 第一次請求之前 |
before_request | 每次請求之前 |
after_request | 每次請求之後 沒有異常 |
teardown_request | 每次請求之後 即使有異常出現 |
實例
@app.before_first_request
def before_first_request():
print('before_first_request')
@app.before_request
def before_request():
print('before_request')
if request.method == 'GET' and request.path == '/form/':
abort(500)
@app.after_request
def before_request(r):
print('before_request',r)
return r
@app.teardown_request
def teardown_request(r):
print('teardown_request')
return r
在藍本中使用
鉤子函數 | 功能描述 |
---|---|
before_app_first_request | 第一次請求之前 |
before_app_request | 每次請求之前 |
after_app_request | 每次請求之後 沒有異常 |
teardown_app_request | 每次請求之後 即使有異常出現 |
實例
@user.before_app_first_request
def before_first_request():
print('before_first_request')
@user.before_app_request
def before_request():
print('before_request')
if request.method == 'GET' and request.path == '/form/':
abort(500)
@user.after_app_request
def after_request(r):
print('after_request',r)
return r
@user.teardown_app_request
def teardown_request(r):
print('teardown_request')
return r
注意:
鉤子函數寫在藍本或者啓動文件中 都可以捕獲到所有的請求和響應(一樣)一個flask中只需要寫一個鉤子函數而不需要重複寫鉤子函數