前言
本來沒想到能這么快出二的,誰知道序列化組件寫上頭了.分享知識真的會上癮....
變更記錄
# 19.3.18 起筆
# 19.3.18 使用SQLAlchemy排序方法
# 19.3.18 補充RESTful時接收參數(POST)
# 19.3.21 補充多個路由匹配同一個view
# 19.3.21 補充SQLAlchemy的OR和AND查詢
# 19.4.15 將POST傳參修改為傳參
正文
SQLAlchemy排序
該排序目前在 百度 上的內容多半是 .order_by('字段') 或 .order_by('-字段')的方式,前一個是正序,后一個是倒序
但是實際運行中雖然可以正常跑起來但是會出現提示
C:\Users\Administrator\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\sql\compiler.py:763: SAWarning: Can't resolve label reference 'vip_order.found_time'; converting to text() (this warning may be suppressed after 1ler.py:763: SAWarning: Can't resolve label reference 'vip_order.found_time'; converting to text() (tng may behis warning may be suppressed after 10 occurrences) util.ellipses_string(element.element),
大概就是 SQLAlchemy 組件認不出來但是語法 mysql 可以認出來,所以給個警告.
打印了一下執行的sql,明白了order_by的方式實際上就是在 sql 語句后拼接
order by 括號內內容
那么,正確的排序(不出提示)應該是怎樣的呢
.order_by(desc('字段')) # 倒序 .order_by('字段') # 正序
要注意的是在倒序時需要先引入 desc
from sqlalchemy import desc
接收參數
以POST為例
我覺得POST是使用最頻繁的提交方法了.之前也看有人說把其他所有請求砍掉只保留POST也可以開發API
RESTFul的POST參數接收比較復雜,但是有友好的錯誤提示,多一點代碼提高前后端交流的速度.會到就是爽到
不說廢話,來看demo
parser = reqparse.RequestParser() # 生成parser parser.add_argument('name', type=int, help='name error', required=True) # 獲取name字段,type指類型,help為定義錯誤時的提示(不寫有默認的),required默認False(沒接收到默認為None)/True為不傳返回錯誤信息(help) parser.add_argument('pwd', type=str, help='pwd error', required=True) # pwd字段,同上 args = parser.parse_args(strict=True) # 獲取傳輸的值/strict=True代表設置如果傳以上未指定的參數主動報錯 name = args['name'] # 獲取用戶名字 pwd = args['pwd'] # 獲取用戶密碼(前端加密)
解釋一下,首先必須要生成parser
然后 add_argument 方法相當於最外層的一個保險,我們之前提到的 友好的錯誤提示 就在這里生效
來看第二行,第二行是校驗 POST提交中 body里的一個key叫 name 的字段,
type意思是restful會簡單校驗一下 key 的 v 的值,不寫type代表不校驗
help意思是restful在任何不匹配的情況下都會返回help的值,如果不定義也有默認值(推薦不寫help,因為自帶的錯誤提示多變且更加友好)
以下為例子
第三個參數 required 如果為False(默認)代表如果用戶沒有傳則為None / 為True代表不傳直接報錯(同上)
args = parser.parse_args(strict=True)
這行代表是否啟用嚴格模式,True 代表嚴格模式啟動,如果傳入不在上面規定的參數則會報錯
Flask-RESTful設置多個路由指向統一的view
有時候我們希望匹配的多個路由進入一個函數/類處理,比如 訪問用戶的url 我們可以GET時帶上id獲取該用戶信息,也希望POST時不帶id代表新增用戶
那么,如果按照之前的方法,啟動 Flask 時會報錯
api.add_resource(Vip, '/website/vip/<int:vip_id>') # 獲取VIP常用信息(匹配url帶有int數字的傳給Vip視圖,url的參數命名為vip_id) api.add_resource(Vip, '/website/vip') # 新建用戶
拋出
AssertionError: View function mapping is overwriting an existing endpoint function: website_1_0.vip
這是因為 Flask-RESTful 內部有一個 endpoint 作為每個路由匹配的view的代號,如果你不寫則默認為你的 view 的名字
所以在啟動時檢測到了兩個名為 vip 的代號,所以會報錯
解決辦法是每次寫 路由 時帶上endpoint同時保證唯一
api.add_resource(Vip, '/website/vip/<int:vip_id>', endpoint='Vip') # 獲取VIP常用信息(匹配url帶有int數字的傳給Vip視圖,url的參數命名為vip_id) api.add_resource(Vip, '/website/vip', endpoint='Vips') # 新建用戶
SQLAlchemy OR 查詢
假設有一個需求是在新用戶注冊時判斷郵箱和昵稱是否重復,重復則攔截.我們有兩種方法
一:建表設置唯一,然后插入數據時捕捉異常
這種方法也是可行的.但是本人認為最好不要等着數據庫報錯,所以此方法這里不談
二:先查詢是否有該用戶,有則報錯
這里介紹方法二
值得注意的是,這里的郵箱和昵稱是兩張表的字段,而且需求是 name 或 email 重復則報錯,這里就用到 OR 查詢
Vip_obj = session.query(Vip).join(VipInfo).filter((Vip.name==name)|(VipInfo.email==email)).first()
我們在filter時將多個判斷用 | 接起來即可
SQLAlchemy AND 查詢
就拿 OR 查詢舉例子 AND和 OR 差不多
Vip_obj = session.query(Vip).join(VipInfo).filter(Vip.name==name, VipInfo.email==email).first()
用 , 鏈接即可,不帶括號