FLASK目錄 前端
1.配置文件python
2.路由系統mysql
3.視圖redis
4.請求相關sql
5.響應相關數據庫
6.模板渲染django
7.閃現json
8.sessionflask
9.中間件後端
10.藍圖
11.特殊的裝飾器
12.WTForms
app.config.from_object('settings.Base') # 更改配置文件
static_folder = 'static', # 靜態文件目錄的路徑 默認當前項目中的static目錄 static_url_path = None, # 靜態文件目錄的url路徑 默認不寫是與static_folder同名,遠程靜態文件時複用 template_folder = 'templates' # template模板目錄, 默認當前項目中的 templates 目錄
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 # 主模塊所在的目錄的絕對路徑,默認項目目錄
@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重定向:永久重定向
1.FBV 函數就是FBV 2.CBV
from flask import views 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.add_url_rule('/user/',User.as_view('endpoint')) 自定義正則 from werkzeug.routing import BaseConverter 1.定義一個類 ,BaseConverter 2.添加到轉換器 app.url_map.converters['reg'] = '類名' 3.使用自定義正則 to_python:匹配url的時候用 to_url:反向生成時候用
request參數(經常使用的) 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 return send_file("2.mp3") # 打開文件並返回客戶端 設置響應頭 obj = make_response('字符串') obj.headers['響應頭']='1111' obj.set_cookie():設置cookie return obj
{{ }} 引用變量 非邏輯代碼時使用 {% %} 邏輯代碼使用 -基本數據類型,能夠執行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('字符串')
閃現,在session中存儲一個數據,讀取時經過pop將數據移出掉 flash('內容',category='ok')
參數:
第一個:內容
第二:分類
get_flashed_messages()獲取flash
參數:
第一:with_categories=True True表明返回一個元祖
第二:category_filter='ok' 篩選條件
默認session的使用
當請求剛到來時,flask讀取cookie中session對應的值,將該值解密並序列化成一個字典,並放入內存 當請求結束時,flask會讀取內存中字典的值,進行序列化+加密,寫入到用戶的cookie中 PERMANENT_SESSION_LIFETIME = timedelta(hours = 1) :小時:hours app.secret_key = 'xxxxxxx' :必需要加的,不加會報錯
flask-sessiom的使用
from flask_session import Session
from flask import session
from redis import Redis
app.config['SESSION_TYPE']='redis'
app.config['SESSION_REDIS'] = Redis()
Session(app)
使用的時候繼續使用flask的session,他會把你存儲的內容放入redis
- app.__call__方法什麼時候觸發 用戶發起請求時才觸發 代碼: class Middleware(): def __init__(self,old): self.old = old def __call__(self, *args, **kwargs): print('前') ret = self.old(*args, **kwargs) print('後') return ret app.wsgi_app = Middleware(app.wsgi_app)
目標:給開發者提供一個目錄結構 from flask import Blueprint ac = Blueprint('ac',__name__,url_prefix='/ac') 註冊藍圖: app.register_blueprint(ac) url_prefix:定義url前綴每次訪問這個藍圖的時候,必須加/ac static_folder = 'xxx' :指定藍圖存儲靜態文件的位置 template_folder='xxx':指定模板存儲的位置 自定義模板和靜態文件,url前綴,
@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) 沒找到頁面走這個之下的函數,有一個參數
12.WTForms
建立數據庫池
import time import pymysql import threading from DBUtils.PooledDB import PooledDB, SharedDBConnection POOL = PooledDB( creator=pymysql, # 使用連接數據庫的模塊 maxconnections=6, # 鏈接池容許的最大鏈接數,0和None表示不限制鏈接數 mincached=2, # 初始化時,連接池中至少建立的空閒的連接,0表示不建立 maxcached=5, # 連接池中最多閒置的連接,0和None不限制 maxshared=3, # 連接池中最多共享的連接數量,0和None表示所有共享。PS: 無用,由於pymysql和MySQLdb等模塊的 threadsafety都爲1,全部值不管設置爲多少,_maxcached永遠爲0,因此永遠是全部連接都共享。 blocking=True, # 鏈接池中若是沒有可用鏈接後,是否阻塞等待。True,等待;False,不等待而後報錯 maxusage=None, # 一個連接最多被重複使用的次數,None表示無限制 setsession=[], # 開始會話前執行的命令列表。如:["set datestyle to ...", "set time zone ..."] 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='123', database='pooldb', charset='utf8' )
使用數據庫池
def func(): # 檢測當前正在運行鏈接數的是否小於最大連接數,若是不小於則:等待或報raise TooManyConnections異常 # 不然 # 則優先去初始化時建立的連接中獲取連接 SteadyDBConnection。 # 而後將SteadyDBConnection對象封裝到PooledDedicatedDBConnection中並返回。 # 若是最開始建立的連接沒有連接,則去建立一個SteadyDBConnection對象,再封裝到PooledDedicatedDBConnection中並返回。 # 一旦關閉連接後,鏈接就返回到鏈接池讓後續線程繼續使用。 conn = POOL.connection() cursor = conn.cursor() cursor.execute('select * from tb1') result = cursor.fetchall() conn.close()
自制sqlhelper
class MySQLhelper(object): def __init__(self, host, port, dbuser, password, database): self.pool = PooledDB( creator=pymysql, # 使用連接數據庫的模塊 maxconnections=6, # 鏈接池容許的最大鏈接數,0和None表示不限制鏈接數 mincached=2, # 初始化時,連接池中至少建立的空閒的連接,0表示不建立 maxcached=5, # 連接池中最多閒置的連接,0和None不限制 maxshared=3, # 連接池中最多共享的連接數量,0和None表示所有共享。PS: 無用,由於pymysql和MySQLdb等模塊的 threadsafety都爲1,全部值不管設置爲多少,_maxcached永遠爲0,因此永遠是全部連接都共享。 blocking=True, # 鏈接池中若是沒有可用鏈接後,是否阻塞等待。True,等待;False,不等待而後報錯 maxusage=None, # 一個連接最多被重複使用的次數,None表示無限制 setsession=[], # 開始會話前執行的命令列表。如:["set datestyle to ...", "set time zone ..."] 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=host, port=int(port), user=dbuser, password=password, database=database, charset='utf8' ) def create_conn_cursor(self): conn = self.pool.connection() cursor = conn.cursor(pymysql.cursors.DictCursor) return conn,cursor def fetch_all(self, sql, args): conn,cursor = self.create_conn_cursor() cursor.execute(sql,args) result = cursor.fetchall() cursor.close() conn.close() return result def insert_one(self,sql,args): conn,cursor = self.create_conn_cursor() res = cursor.execute(sql,args) conn.commit() print(res) conn.close() return res def update(self,sql,args): conn,cursor = self.create_conn_cursor() res = cursor.execute(sql,args) conn.commit() print(res) conn.close() return res sqlhelper = MySQLhelper("127.0.0.1", 3306, "root", "1233121234567", "dragon") # sqlhelper.fetch_all("select * from user where id=%s",(1)) # sqlhelper.insert_one("insert into user VALUES (%s,%s)",("jinwangba",4)) # sqlhelper.update("update user SET name=%s WHERE id=%s",("yinwangba",1))