flask - 進階
阿新 • • 發佈:2020-08-06
flask 進階
上下文管理和SQLHelper
```python import pymysql from DBUtils.PooledDB import PooledDB class SqlHelper(object): def __init__(self): self.pool = PooledDB( creator=pymysql, # 使用連結資料庫的模組 maxconnections=6, # 連線池允許的最大連線數,0和None表示不限制連線數 mincached=2, # 初始化時,連結池中至少建立的連結,0表示不建立 blocking=True, # 連線池中如果沒有可用連線後,是否阻塞等待。True,等待;False,不等待然後報錯 ping=0, # ping MySQL服務端,檢查是否服務可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always host='127.0.0.1', port=3306, user='root', password='222', database='cmdb', charset='utf8' ) def open(self): conn = self.pool.connection() cursor = conn.cursor() return conn,cursor def close(self,cursor,conn): cursor.close() conn.close() def fetchall(self,sql, *args): """ 獲取所有資料 """ conn,cursor = self.open() cursor.execute(sql, args) result = cursor.fetchall() self.close(conn,cursor) return result def fetchone(self,sql, *args): """ 獲取所有資料 """ conn, cursor = self.open() cursor.execute(sql, args) result = cursor.fetchone() self.close(conn, cursor) return result def __enter__(self): return self.open()[1] def __exit__(self, exc_type, exc_val, exc_tb): print(exc_type, exc_val, exc_tb) db = SqlHelper() ```
概要
- wsgi
- 建立flask物件
- 模板
- 靜態檔案
- 路由系統
- 路由的應用:裝飾器(推薦)、方法
- 動態路由
- 檢視
- FBV
- CBV
- 模板
- 繼承
- include
- 自定義標籤
- 特殊裝飾器
- before_request充當中介軟體角色
詳細
1.wsgi 找原始碼的流程
from werkzeug.serving import run_simple from werkzeug.wrappers import BaseResponse def func(environ, start_response): print('請求來了') response = BaseResponse('你好') return response(environ, start_response) if __name__ == '__main__': run_simple('127.0.0.1', 5000, func)
"""
1.程式啟動,等待使用者請求到來
app.run()
2.使用者請求到來 app()
app.__call__
"""
from flask import Flask
app = Flask(__name__)
@app.route('/index')
def index():
return 'hello world'
if __name__ == '__main__':
app.run()
2.flask物件
靜態檔案的處理。
推薦
from flask import Flask,render_template app = Flask(__name__,template_folder='templates',static_folder='static') @app.route('/index') def index(): return render_template('index.html') if __name__ == '__main__': app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>首頁</h1>
<img src="/static/xx/xx/mm.jpg" />
<!-- 建議 -->
<img src="{{ url_for('static',filename='xx/xx/mm.jpg')}}" />
</body>
</html>
3.配置檔案
3.1 基於全域性變數
3.2 基於類的方式
4.路由系統
-
路由的兩種寫法
def index(): return render_template('index.html') app.add_url_rule('/index', 'index', index) # 公司裡一般用這種方式 @app.route('/login') def login(): return render_template('login.html')
-
路由載入的原始碼流程
- 將url和函式打包成為 rule 物件 - 將rule物件新增到map物件中。 - app.url_map = map物件
-
動態路由
@app.route('/login') def login(): return render_template('login.html') @app.route('/login/<name>') def login(name): print(type(name)) return render_template('login.html') @app.route('/login/<int:name>') def login(name): print(type(name)) return render_template('login.html')
-
支援正則表示式的路由
from flask import Flask,render_template app = Flask(__name__) from werkzeug.routing import BaseConverter class RegConverter(BaseConverter): def __init__(self, map, regex): super().__init__(map) self.regex = regex app.url_map.converters['regex'] = RegConverter @app.route('/index/<regex("\d+"):x1>') def index(x1): return render_template('index.html') if __name__ == '__main__': app.run()
5.檢視
5.1 FBV
def index():
return render_template('index.html')
app.add_url_rule('/index', 'index', index)
# 公司裡一般用這種方式
@app.route('/login')
def login():
return render_template('login.html')
5.2 CBV
from flask import Flask,render_template,views
app = Flask(__name__,)
def test1(func):
def inner(*args,**kwargs):
print('before1')
result = func(*args,**kwargs)
print('after1')
return result
return inner
def test2(func):
def inner(*args,**kwargs):
print('before2')
result = func(*args,**kwargs)
print('after2')
return result
return inner
class UserView(views.MethodView):
methods = ['GET',"POST"]
decorators = [test1,test2] #裝飾器傳
def get(self):
print('get')
return 'get'
def post(self):
print('post')
return 'post'
app.add_url_rule('/user', view_func=UserView.as_view('user')) # endpoint 反向生成
if __name__ == '__main__':
app.run()
6.模板
6.1 基本用法
flask比django更加接近Python。
from flask import Flask,render_template
app = Flask(__name__,)
def func(arg):
return '你好' + arg
@app.route('/md')
def index():
nums = [11,222,33]
return render_template('md.html',nums=nums,f=func)
if __name__ == '__main__':
app.run()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>頭</h1>
{% block content %} {% endblock %}
<h1>底</h1>
</body>
</html>
<form action="">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
<input type="text">
</form>
{% extends 'layout.html' %}
{% block content %}
<h1>MD</h1>
{% include 'form.html' %}
{{ f("汪洋") }}
{% endblock %}
6.2 定義全域性模板方法
from flask import Flask,render_template
app = Flask(__name__,)
@app.template_global() # {{ func("趙海宇") }}
def func(arg):
return '海狗子' + arg
@app.template_filter() # {{ "趙海宇"|x1("孫宇") }}
def x1(arg,name):
return '海狗子' + arg + name
@app.route('/md/hg')
def index():
return render_template('md_hg.html')
if __name__ == '__main__':
app.run()
注意:在藍圖中註冊時候,應用返回只有本藍圖。
7.特殊裝飾器
from flask import Flask,render_template,request
app = Flask(__name__)
@app.before_request
def f1():
if request.path == '/login':
return
print('f1')
# return '123'
@app.after_request
def f10(response):
print('f10')
return response
@app.route('/index')
def index():
print('index')
return render_template('index.html')
if __name__ == '__main__':
app.run()
多個裝飾器
from flask import Flask,render_template,request
app = Flask(__name__)
@app.before_request
def f1():
print('f1')
@app.before_request
def f2():
print('f2')
@app.after_request
def f10(response):
print('f10')
return response
@app.after_request
def f20(response):
print('f20')
return response
@app.route('/index')
def index():
print('index')
return render_template('index.html')
if __name__ == '__main__':
app.run()
app.__call__
注意:before_after request可以在藍圖中定義,在藍圖中定義的話,作用域只在本藍圖。
8.小細節
from flask import Flask,render_template
app = Flask(__name__,)
@app.route('/index')
def index():
return render_template('index.html')
@app.before_request
def func():
print('xxx')
def x1():
print('xxx')
app.before_request(x1)
if __name__ == '__main__':
app.run()
:threading.local
import time
import threading
# 當每個執行緒在執行 val1.xx=1 ,在內部會為此執行緒開闢一個空間,來儲存 xx=1
# val1.xx,找到此執行緒自己的記憶體地址去取自己儲存 xx
val1 = threading.local()
def task(i):
val1.num = i
time.sleep(1)
print(val1.num)
for i in range(4):
t = threading.Thread(target=task,args=(i,))
t.start()