Django框架(十七)-- CBV源碼分析、restful規範、restframework框架

1、CBV源碼分析

一、url層的使用CBV

from app01 import views url(r'book/',views.Book.as_view)

二、as_view方法

as_view是一個類方法,其實是一個閉包函數(內層函數包含對外層做用域的使用)前端

請求來了之後,調用as_view方法,調用函數中的view方法,view方法是調用了dispatch方法django

@classonlymethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs # 若是調用的類Book沒有寫dispatch方法,就會調用View中的dispatch方法
            return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs return view

三、view方法

view 方法是一個閉包函數,最終調用了 dispatch 方法

四、dispatch方法(能夠在視圖層的CBV中重寫)

getattr(self, 'get'[,default])   # 獲取對象的get屬性的內存地址,若是沒有get,返回默認值
setattr(self, 'get', 'get__all')  # 至關於將get的內存地址設置爲get__all 的內存地址
hasattr(self,'get')     # 判斷對象是否有get 屬性

dispatch方法至關因而根據不一樣的請求方式,分發到對應的函數屬性中編程

def dispatch(self, request, *args, **kwargs): # http_method_names --> ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']
    if request.method.lower() in self.http_method_names: # 這裏的self.http_method_not_allowed 是默認值,若是沒有改method,獲取其地址
        # 若是是get請求,那麼handler就是get;如果post請求,handler至關於post
        handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs)

五、views層的CBV

class Books(View): # 獲取全部圖書
    def get(self, request): print(type(request)) response = {'status': 100, 'data': None} books = models.Book.objects.all() # 先構造出全部書籍的字典的列表
        ll = [{'name': book.name, 'price': book.price} for book in books] # 返回數據是json格式數據
        response['data'] = ll # safe = True 表示數據能夠是列表
        return JsonResponse(response, safe=False)

六、CBV執行過程總結

請求 --> 調用View中的as_view --> 調用as_view中的閉包view --> view中會實例化產生一個對象 --> 調用對象的dispatch --> 沒有,去類中找dispatch --> 沒有dispatch --> 
去View中找,找到dispatch,執行 --> 分發到不一樣的函數,執行並返回

2、restful規範

resful規範的接口,用fbv和cbv均可以,自定義方法,CBV中重寫,FBV中利用裝飾器json

一、什麼是restful

  • REST與技術無關,表明的是一種軟件架構風格,REST是Representational State Transfer的簡稱,中文翻譯爲「表徵狀態轉移」
  • 面向資源編程,網絡中的全部的數據都是資源

二、10條規範

(1)https協議

API與用戶的通訊協議,老是使用 HTTPs協議 ------ https比http安全api

(2)域名

https://api.example.com    ----- 儘可能將API部署在專用域名(會存在跨域問題) https://127.0.0.1/api/   ----- 簡單,推薦使用

(3)版本

每一個接口都應有版本跨域

https://example/api/v2   ----- v2 版本

(4)路徑

視網絡上任何東西都是資源,均使用名詞表示(可複數)數組

https://example/api/v1/zoos https://example/api/v1/animals https://example/api/v1/employees

(5)method

  • GET :從服務器取出資源(一項或多項)
  • POST :在服務器新建一個資源
  • PUT :在服務器更新資源(客戶端提供改變後的完整資源)
  • PATCH :在服務器更新資源(客戶端提供改變的屬性)
  • DELETE :從服務器刪除資源

(6)過濾

經過在url上傳參的形式傳遞搜索條件安全

https://example/api/v1/zoos?limit=10 https://example/api/v1/animals?offset=20 https://example/api/v1/employees?name=tom

(7)狀態碼

請求回去,須要有狀態碼服務器

200 OK - [GET]:服務器成功返回用戶請求的數據,該操做是冪等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。 202 Accepted - [*]:表示一個請求已經進入後臺排隊(異步任務) 204 NO CONTENT - [DELETE]:用戶刪除數據成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操做,該操做是冪等的。 401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。 403 Forbidden - [*] 表示用戶獲得受權(與401錯誤相對),可是訪問是被禁止的。 404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操做,該操做是冪等的。 406 Not Acceptable - [GET]:用戶請求的格式不可得(好比用戶請求JSON格式,可是隻有XML格式)。 410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再獲得的。 422 Unprocesable entity - [POST/PUT/PATCH] 當建立一個對象時,發生一個驗證錯誤。 500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將沒法判斷髮出的請求是否成功。

(8)錯誤處理

應返回錯誤信息,error當作keyrestful

{status:100,error:'錯誤信息寫上'}

(9)返回結果

針對不一樣操做,服務器向用戶返回的結果應該符合如下規範

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

(10)返回結果中提供連接(Hypermedia)

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

{ status:100 msg:成功 url:127.0.0.1/books/1 }

3、drf(Django restframework)框架

一、什麼是drf

它是一個app,只是用來快速的構建restful規範的接口

二、drf的使用

必定要在settings中註冊 INSTALLED_APPS=[rest_framework]

from rest_framework.views import APIView class Books(APIView): # 如今這個request對象,已經不是原來django中的request對象了,它是rest_framework.request下的Request
    def put(self, request, pk): # django.core.handlers.wsgi.WSGIRequest----原來的djagno中的request的類
        # 如今的request已經成了:rest_framework.request.Request
        # 之後再取數據,直接從request.data中取
        print(request.data) # 前端傳過來的編碼格式:json格式:{'name': '水都是', 'price': '15'}
        # 前端傳過來的編碼格式:urlencoded格式:<QueryDict: {'name': ['紅樓夢'], 'price': ['15']}>
        # request.data是誰的對象?
        # request.data不一樣編碼格式過來,它多是不一樣類的對象,可是用法是同樣的

        # 原來的request是:request._request
        print(type(request._request)) print(request._request.GET) # 也能取出來(method,GET,POST,BODY)
        print(request.GET) return JsonResponse({'status': 100, 'msg': '修改爲功'})

注意點

  • request.data 是個方法,經過property裝飾器包裝成了屬性,前臺傳過來body體中數據的數據,放在裏面
    • 前端傳過來的編碼格式:json格式:{'name': '水都是', 'price': '15'}
    • 前端傳過來的編碼格式:urlencoded格式:<QueryDict: {'name': ['紅樓夢'], 'price': ['15']}>
  • request.query_params 這個是原來GET中的數據
  • request把原來的request包裝進去了
  • 一旦繼承了APIView類,request就被包裝過,再也不是Django中那個request,而是rest_framework.request.Request的對象
  • csrf_exempt:局部禁用csrf(csrf是能夠局部使用,局部禁用),rest_framework有自身的方法放置csrf攻擊,不須要寫{% csrf_token %}

三、rest_framework中CBV執行流程

請求 --> rest_framework的as_view --> super調用父類View的as_view --> 父類中as_view調用比和函數view,實例化產生一個對象 --> 調用改對象的dispatch --> 自身沒有,類中也沒有,去父類中APIView中 --> 有dispatch方法 --> 調用rest_framework中的dispatch --> 分發到get、post、put等函數中執行
相關文章
相關標籤/搜索