程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

django的drf入門規范

編輯:Python

drf入門規范

一、web應用模式

  • 在開發wdb應用時,有兩種應用方式

1、前後端不分離

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DIuZRcLc-1635934913862)(image-20210831100921267.png)]

2、前後端不分離

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-rdtYnJsZ-1635934913863)(image-20210831100951626.png)]

二、API接口

為了在團隊內部形成共識、防止個人習慣差異引起的混亂,我們需要找到一種大家都覺得很好的接口實現規范,而且這種規范能夠讓後端寫的接口,用途一目了然,減少雙方之間的合作成本。

通過網絡,規定了前後端信息交互規則的url鏈接,也就是前後端信息交互的媒介

Web API接口和一般的url鏈接還是有區別的,Web API接口簡單概括有下面四大特點

  • url:長得像返回數據的url鏈接

[]: https://api.map.baidu.com/place/v2/search

  • 請求方式:get、post、put、patch、delete

  • 請求參數:json或xml格式的key-value類型數據

""" ak:6E823f587c95f0148c19993539b99295 region:上海 query:肯德基 output:json """
  • 響應結果:json或xml格式的數據

    • 上方請求參數的output參數值決定了響應數據的格式
    • 數據
# xml格式
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=xml
#json格式
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295&region=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=json
{

"status":0,
"message":"ok",
"results":[
{

"name":"肯德基(羅餐廳)",
"location":{

"lat":31.415354,
"lng":121.357339
},
"address":"月羅路2380號",
"province":"上海市",
"city":"上海市",
"area":"寶山區",
"street_id":"339ed41ae1d6dc320a5cb37c",
"telephone":"(021)56761006",
"detail":1,
"uid":"339ed41ae1d6dc320a5cb37c"
}
...
]
}

三、Postman:接口測試工具

Postman是一款接口調試工具,是一款免費的可視化軟件,同時支持各種操作系統平台,是測試接口的首選工具。

Postman可以直接從官網:https://www.getpostman.com/downloads/下載獲得,然後進行傻瓜式安裝。

四、restful接口規范

REST全稱是Representational State Transfer,中文意思是表述(編者注:通常譯為表征性狀態轉移)。 它首次出現在2000年Roy Fielding的博士論文中。

RESTful是一種定義Web API接口的設計風格,尤其適用於前後端分離的應用模式中。

這種風格的理念認為後端開發任務就是提供數據的,對外提供的是數據資源的訪問接口,所以在定義接口時,客戶端訪問的URL路徑就表示這種要操作的數據資源。

事實上,我們可以使用任何一個框架都可以實現符合restful規范的API接口。

1、數據的安全保障

  • url鏈接一般都采用https協議進行傳輸

    注:采用https協議,可以提高數據交互過程中的安全性

2、url特征表現

  • 用api關鍵字標識接口url:

    • https://api.baidu.com
    • https://www.baidu.com/api

    注:看到api字眼,就代表該請求url鏈接是完成前後台數據交互的

3、多數據版本共存

  • 在url鏈接中標識數據版本

    • https://api.baidu.com/v1
    • https://api.baidu.com/v2

    注:url鏈接中的v1、v2就是不同數據版本的體現(只有在一種數據資源有多版本情況下)

4、數據既資源,均使用名詞(可用復數)

  • 接口一般都是完成前後台數據的交互,交互的數據我們稱之為資源

    • https://api.baidu.com/users
    • https://api.baidu.com/books
    • https://api.baidu.com/book

    注:一般提倡用資源的復數形式,在url鏈接中獎勵不要出現操作資源的動詞,錯誤示范:https://api.baidu.com/delete-user

  • 特殊的接口可以出現動詞,因為這些接口一般沒有一個明確的資源,或是動詞就是接口的核心含義

    • https://api.baidu.com/place/search
    • https://api.baidu.com/login

5、資源操作由請求方式決定

  • 操作資源一般都會涉及到增刪改查,我們提供請求方式來標識增刪改查動作
    • https://api.baidu.com/books - get請求:獲取所有書
    • https://api.baidu.com/books/1 - get請求:獲取主鍵為1的書
    • https://api.baidu.com/books - post請求:新增一本書書
    • https://api.baidu.com/books/1 - put請求:整體修改主鍵為1的書
    • https://api.baidu.com/books/1 - patch請求:局部修改主鍵為1的書
    • https://api.baidu.com/books/1 - delete請求:刪除主鍵為1的書

6、過濾在通過在url上傳參傳遞搜索條件

  • https://api.example.com/v1/zoos?limit=10:指定返回記錄的數量
  • https://api.example.com/v1/zoos?offset=10:指定返回記錄的開始位置
  • https://api.example.com/v1/zoos?page=2&per_page=100:指定第幾頁,以及每頁的記錄數
  • https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
  • https://api.example.com/v1/zoos?animal_type_id=1:指定篩選條件

7、響應狀態碼

7.1 正常響應

  • 響應狀態碼2xx
    • 200:常規請求
    • 201:創建成功

7.2 重定向響應

  • 響應狀態碼3xx
    • 301:永久重定向
    • 302:暫時重定向

7.3 客戶端異常

  • 響應狀態碼4xx
    • 403:請求無權限
    • 404:請求路徑不存在
    • 405:請求方法不存在

7.4 服務器異常

  • 響應狀態碼5xx
    • 500:服務器異常

8、錯誤處理

{

error: "無權限操作"
}

9、返回結果,針對不同操作,服務器向用戶返回的結果應該符合以下規范

GET /collection:返回資源對象的列表(數組)
GET /collection/resource:返回單個資源對象
POST /collection:返回新生成的資源對象
PUT /collection/resource:返回完整的資源對象
PATCH /collection/resource:返回完整的資源對象
DELETE /collection/resource:返回一個空文檔

10、需要url請求的資源需要訪問資源的請求鏈接

# Hypermedia API,RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什麼
{

"status": 0,
"msg": "ok",
"results":[
{

"name":"肯德基(羅餐廳)",
"img": "https://image.baidu.com/kfc/001.png"
}
...
]
}

比較好的接口返回

# 響應數據要有狀態碼、狀態信息以及數據本身
{

"status": 0,
"msg": "ok",
"results":[
{

"name":"肯德基(羅餐廳)",
"location":{

"lat":31.415354,
"lng":121.357339
},
"address":"月羅路2380號",
"province":"上海市",
"city":"上海市",
"area":"寶山區",
"street_id":"339ed41ae1d6dc320a5cb37c",
"telephone":"(021)56761006",
"detail":1,
"uid":"339ed41ae1d6dc320a5cb37c"
}
...
]
}

五、序列化

api接口開發,最核心最常見的一個過程就是序列化,所謂序列化就是把數據轉換格式,序列化可以分兩個階段:

序列化: 把我們識別的數據轉換成指定的格式提供給別人。

例如:我們在django中獲取到的數據默認是模型對象,但是模型對象數據無法直接提供給前端或別的平台使用,所以我們需要把數據進行序列化,變成字符串或者json數據,提供給別人。

反序列化:把別人提供的數據轉換/還原成我們需要的格式。

例如:前端js提供過來的json數據,對於python而言就是字符串,我們需要進行反序列化換成模型類對象,這樣我們才能把數據保存到數據庫中。

六、drf規范(django rest framework)

核心思想: 縮減編寫api接口的代碼

Django REST framework是一個建立在Django基礎之上的Web 應用開發框架,可以快速的開發REST API接口應用。在REST framework中,提供了序列化器Serialzier的定義,可以幫助我們簡化序列化與反序列化的過程,不僅如此,還提供豐富的類視圖、擴展類、視圖集來簡化視圖的編寫工作。REST framework還提供了認證、權限、限流、過濾、分頁、接口文檔等功能支持。REST framework提供了一個API 的Web可視化界面來方便查看測試接口。

1、django rest framework的特點

  • 提供了定義序列化器Serializer的方法,可以快速根據 Django ORM 或者其它庫自動序列化/反序列化;
  • 提供了豐富的類視圖、Mixin擴展類,簡化視圖的編寫;
  • 豐富的定制層級:函數視圖、類視圖、視圖集合到自動生成 API,滿足各種需要;
  • 多種身份認證和權限認證方式的支持;[jwt]
  • 內置了限流系統;
  • 直觀的 API web 界面;
  • 可擴展性,插件豐富

在Django裡使用restframework需要在INSTALLED_APPS裡添加"rest_framework"

接下來就可以使用DRF提供的功能進行api接口開發了。在項目中如果使用rest_framework框架實現API接口,主要有以下三個步驟:

  • 將請求的數據(如JSON格式)轉換為模型類對象
  • 操作數據庫
  • 將模型類對象轉換為響應的數據(如JSON格式)

2、CBV源碼分析

# urls.py
path('bookview/',views.bookview.as_view()),
# views.py
from rest_framework.views import View
class bookview(View):
def get(self):
return HttpResponse('ok')
  • 源碼分析
""" 進入View源碼中,首先找到as_view方法 """
@classonlymethod # 類方法,直接由類調用
def as_view(cls, **initkwargs):
def view(request, *args, **kwargs):
………………
return self.dispatch(request, *args, **kwargs) # 此處調用了dispatch方法
return view # 將view方法返回
# dispatch方法(重要)
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs)
""" dispatch方法主要是對views.py裡的bookview裡的方法進行判斷 判斷其方法是否在http_method_names裡; http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] 如果存在使用getattr進行反射,此時的self便是bookview類 """

3、APIView源碼分析

# urls.py
path('bookview/',views.bookview.as_view()),
# views.py
from rest_framework.views import APIView
class bookview(View):
def get(self):
return HttpResponse('ok')
  • 源碼分析
""" 進入到APIView源碼裡 """
class APIView(View):
……
@classmethod
def as_view(cls, **initkwargs):
……
view = super().as_view(**initkwargs)
view.cls = cls
view.initkwargs = initkwargs
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.
return csrf_exempt(view)
""" 能夠看到APIView實際上就是繼承View,並且直接繼承了View裡的as_view方法絲毫未改 唯獨有一點不同就是return csrf_exempt(view) 在django的中間間中有這樣一行代碼'django.middleware.csrf.CsrfViewMiddleware', 這便是防止csrf跨站請求偽造的 而csrf_exempt(view)就是@csrf_exempt裝飾器的另一種寫法,兩者一摸一樣 """
APIView執行流程分析
# 請求來了,會執行views.BookView.as_view()(request)---->觸發APIView的as_view
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs) # 調用了View的as_view
return csrf_exempt(view) # 去掉了csrf的認證,跟原來加裝飾器一樣
# 假設get請求來了,執行view()--最重要的-->self.dispatch()--》APIView的
def dispatch(self, request, *args, **kwargs):
# 把原來的request對象,包裝成了新的request對象,是drf的request
request = self.initialize_request(request, *args, **kwargs)
try:
# 執行了三大認證:認證,權限,頻率
self.initial(request, *args, **kwargs)
# 跟原來一模一樣
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 真正的執行視圖類中的方法,如果有異常,被捕獲了
response = handler(request, *args, **kwargs)
except Exception as exc:
response = self.handle_exception(exc)
return self.response
# 重點:
apiview:干了三件事
-把老的request對象包裝成了新的request對象
-通過APIView的initialize_request,包裝的
-以後再在視圖類中用的request對象,都是新的
-在執行視圖類中的方法之前,執行了三大認證
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
-處理全局異常
只要繼承了APIView,以後用的request對象,就是drf的request對象了
在執行視圖類的方法之前,會先執行三大認證,如果有異常,會被捕獲並處理

4、request源碼解析

# view.py
from rest_framework.request import Request
from rest_framework.views import APIView
class bookview(APIView):
def get(self,request):
return HttpResponse('ok')
""" # from rest_framework.request import Request # 重點 -老的django的request在drf的request._request中 -新的request用起來跟原來一模一樣用,沒有一點區別 -對象.屬性,會觸發類的 __getattr__方法 -重寫了__getattr__ return getattr(self._request, attr) -新的request多個一個data屬性--》所有post提交的數據,都放在它中 """

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved