哇,昨天組里進行總結的時候,小哥哥和小姐姐真是把我給秀到了,跟他們一比,我總結的太垃圾了,嚶嚶嚶。因為我平常不怎么總結,總結的話,有word還有紙質的,現在偏向於紙質,因為可以練練字。個人觀點是,掌握了就不需要總結,因為已經會了,總結沒什么用。如果需要總結只能說是還不夠會。不過總結也有總結的好處,可以把整個過程再重新梳理一遍,如果時間比較充足的話,還是不錯的方法。現在還是每天總結一下吧,要不然最后不好看。開始正題flask中的restful
一、關於Restful
Restful是目前最流行的api設計規范,用於web數據接口的設計
什么又是api?
按照我的理解,比如print(),這就是一個api。
def print(self, *args, sep=' ', end='\n', file=None): # known special case of print
""" print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream. """
pass
可以看到print()並不是一開始就有在終端中輸出打印的功能,而是被python的創始人事先已經規范好的一個函數叫print,這個函數里面才有打印的功能
二、Restful基礎
restful定義的api可以是一個接口,這個接口在定義url鏈接的時候,不能存在動詞,一個個進行詳細說明
在flask(因為我學的flask,菜的真實)中有一個視圖函數(看我要說的准確一點啦)叫做@app.route,這個函數不能詳細說,只需要知道是一個定義路徑的就可以,比如我要寫一個/index/路徑,那么我們就可以是
@app.route('/index/') def index(): return "hello,world"
這樣就已經完成一個index的路徑了。還想要仔細了解話,這個東西是裝飾器,裝飾器也算一個挺復雜的函數。可以用雙手搜下"flask 裝飾器",具體理解就只能看個人啦~
狀態碼:
200 正常
3xx 重定向
4xx 客戶端錯誤
5xx 服務器錯誤
http的請求
get、post、put、head、delete、connect、options、trace這個最好要知道,因為后面會用到,想具體了解到話可以參考一本叫做《圖解HTTP》的一本書
三、Restful的動詞
在Restful中有五種請求方式,並且這五種請求方法不像在http里面只是一個請求的方法,這五種請求方法還需要記住,並且按照專業術語的話,它們應稱之為“動詞”。
get 讀取
post 新建
put 更新
patch 也是更新,但只是部分更新(比如我只更新一個數據表中的一個參數,那么用patcha就會只更新這個參數,不會更新其他的東西)
delete 刪除
了解了這五種請求方式之后,按照規范,在RestFul里面鏈接路由的時候,不能在名詞里面加上動詞。名詞就是開發人員編寫的路徑名,但是路徑名里面不能包含動詞。
比如一個正確的url鏈接是/index/,這里面是沒有動詞的。錯誤的url鏈接是/get-index/這是一個錯誤的url鏈接,因為在get-index里面,包含動詞get,在定義路徑的時候,python會報錯。
掌握完這些前期知識之后,我們來說下一個簡單的Restful api實現
四、簡單的hello world
from flask import Flask,redirect,url_for from flask_restful import Api,Resource,reqparse app = Flask(__name__) # 先綁定一個api,進行初始化操作 api = Api(app) class LoginView(Resource): def get(self): return {"simple":"hello world"}
api.add_resource(LoginView , '/' ,endpoint= 'login')
if __name__ == '__main__':
app.run()
前面兩個from都是進行導入模板的,如果沒有的話,需要進行安裝。如果想用flask_restful,那么就可以在windows的命令行,或者Pycharm的虛擬終端中輸入pip install flask_restful。這樣就可以安裝了。
這里簡單說明下兩個模板中的作用,from flask中的flask是Python中的一個框架,如果要想用flask框架的話,那么就必須要有這個庫。flask_restful這個是restful用的。restful不是python中的內置模板,肯定是要進行導入啦。
app = Flask(__name__) 這是初始化一個flask模型
api = Api(app)這是將api和flask綁定到一塊
LoginView繼承了一個Resource的類,這個類我也沒有仔細的了解,待我了解之后,我再進行補充。先記着,必須要繼承Resource的類,才能寫api
下面定義的方法比較重要
def get() 代表了是get方法傳輸數據,傳輸的數據都是json(就是一個格式化輸出,比較規范的一個字典,不用過多糾結)。如果是def post()就代表了是post方法傳輸數據。然后根據函數的定義,一個函數要有一個返回值,因為是json的傳輸格式,所以就要是返回一個字典。
重要的部分是要把這個api要有一個展示的Url鏈接呀,那么我們就用api.add_resource()這個函數進行展現。第一個參數是定義的視圖名LoginView,第二參數是url的鏈接是在/,比如是http;//127.0.0.1:5000那么我想訪問/頁面,就需要是http://127.0.0.1/,endpoint這個參數是后來Url_for反轉的時候用到的。這樣就能訪問了,不要忘記簡單但是又核心的main,如果main丟了,程序如何執行呢?嘻嘻
拓展一下
如果是一個詳情頁面展示呢?就是在url里面是/index/1/ ,/index/2/,/index/3,/index/..../ 這樣的結構呢?難道我每次都需要是需要一個api.add_resource(xxx視圖,/index/1/),注意仔細觀看除了/index/,后面的1,2,3,4.....都是有規律的。如果我們可以把這些1,2,3,4設置為變量就好了,沒錯,在flask中是可以進行操作的。
我貼代碼先看一下
from flask import Flask,redirect,url_for from flask_restful import Api,Resource,reqparse app = Flask(__name__) # 先綁定一個api,進行初始化操作 api = Api(app) class LoginView(Resource): def get(self , username): return {"simple" : 'hello ,world'} api.add_resource(LoginView , '/<username>/' ,endpoint= 'login') # @app.route('/login1/') def login1(): return redirect(url_for('login' ,username = '1')) if __name__ == '__main__': app.run()
這里利用了username進行傳值,通過視圖函數login1來傳遞username的屬性值,進而訪問的時候以http://127.0.0.1:5000/1/就可以訪問的到了。<username>,代表了這是個可變的路由。可以參考下flask官方文檔中對路由的解釋 http://docs.jinkan.org/docs/flask/quickstart.html#routing
下面貼上效果圖
這樣的話一個稍微不是hello world的hello world,就算完成了。
Restful進階:
post提交方法,前面我們已經說過get方法是讀取,post方法是新建啦。我們用post方法演示一下,先貼代碼
from flask import Flask,redirect,url_for from flask_restful import Api,Resource,reqparse app = Flask(__name__) # 先綁定一個api,進行初始化操作 api = Api(app) class LoginView(Resource): def post(self): parser = reqparse.RequestParser() # reqparse 是一個類似於WTforms驗證的一個模板,用這個模板的時候,需要先進行引用,然后和WTForms的功能就差不了,就是一個驗證用戶輸入的功能。
username = parser.add_argument('username' ,type = str , help = 'you xu yao yi ge zheng que de shuzi' ,required = True) # 定義一個username,說明用戶需要傳入關於username的一個值()后面的都是參數.括號里面的參數可以先不考慮 password = parser.add_argument('password' , type = str , help = 'you xu yao yi ge zheng que de mima') # 定義一個password,說明用戶需要傳入關於password的一個值()后面的都是參數.括號里面的參數可以先不考慮 args = parser.parse_args() # 對用戶傳入的參數進行解析,不解析的話,是會報錯的 print(args) return {"username" : "balala"} api.add_resource(LoginView , '/') if __name__ == '__main__': app.run()
運行的結果是,瀏覽器默認的是get方式提交。而我們定義的是post方式提交
post方式提交(這里用到的是MantraPortable瀏覽器,個人感覺這款瀏覽器還是非常方便的。如果好像谷歌的postman的插件也是可以的,或者用burpsuit抓包進行修改,再或者在火狐里面有hackbar(這個目前付費了,emmn ,可以百度去搜下教程,都是一樣的,只要能提交post數據就可以)
這是我們把username和password都進行提交了,如果我們只提交一個password呢?
咦,可以看到兩個結果不一樣,這是為什么呢?
username = parser.add_argument('username' ,type = str , help = 'you xu yao yi ge zheng que de shuzi' ,required = True) password = parser.add_argument('password' , type = str , help = 'you xu yao yi ge zheng que de mima')
因為username里面有個required的參數,這個參數我的理解是username必須要有值,才能回顯正確的字段。如果沒有值的話,就回顯help里面的內容。help就是一個提示的作用,萬一用戶輸入的與我們想象的不一致,那我們可以進行提示下呀。不過這里有個小技巧,如果說help里面提示是中文的話,瀏覽器會進行轉碼,至於轉碼如何解決就只能百度去搜索了.......
補充下參數的內容:
default:默認值,如果這個字段沒有設置值,那么就會使用default參數指定的值
required:是否必須。默認是false,如果設置為True,那么這個參數就必須提交上來。
type:這個參數的數據類型,如果指定,那么將使用指定的數據類型來強制轉換提交上來的值
choices:選項。提交上來的值,只有滿足這個選項中的值才符合驗證通過,否則驗證不通過。這個屬性是一個列表,使用的時候要注意一下
help:錯誤信息,如果驗證失敗后就將才用這個help里面的內容
trim:是否去掉前后的空格
目前參考: https://www.runoob.com/w3cnote/restful-architecture.html
http://www.ruanyifeng.com/blog/2018/10/restful-api-best-practices.html
(待我慢慢寫,寫精華,不寫一般般的帖子)