1. 程式人生 > >Django Rest framework實現流程

Django Rest framework實現流程

目錄

一 什麼是restful架構
二 Django REST framework簡介
三 Django REST framework原理
四 Django REST framework原始碼流程
五 Django REST framework實現使用者登入

一 什麼是restful架構

這裡結合阮一峰的部落格看看就更完美了 http://www.ruanyifeng.com/blog/2011/09/restful.html

1、起源

REST即表述性狀態傳遞(英文:Representational State Transfer,簡稱REST)是Roy Fielding博士在2000年他的博士論文中提出來的一種軟體架構風格。它是一種針對網路應用的設計和開發方式,可以降低開發的複雜性,提高系統的可伸縮性。
目前在三種主流的Web服務實現方案中,因為REST模式的Web服務與複雜的SOAP和XML-RPC對比來講明顯的更加簡潔,越來越多的web服務開始採用REST風格設計和實現。例如,Amazon.com提供接近REST風格的Web服務進行圖書查詢;雅虎提供的Web服務也是REST風格的

2、框架組成

根據rest的論文,我們大致可以把restful架構分成以下幾個部分

1. 資源

資源就是網路中的具體資訊。比如說招聘資訊、美女圖片、NBA賽事、股票資訊、歌曲等等。每一種具體資源都可以用一個URI(統一資源定位符)指向它。如果想要獲取這些資源,則直接訪問它的URI就可以。
有很多公共的URI,例如阿里雲的api市場就提供了很多種的api,每種api代替了具體的資源,每種資源你都可以通過訪問api獲取到。
例如訪問下面圖片中的api地址,就可以獲取到滬深港股票歷史行情資料

2. 表現方式

在資源裡我們提到了阿里雲提供了很多api,api獲取了是一些靜態資源,而表現方式就會為了處理獲取到的這些資源以什麼樣的形式展示給訪問者。
現在常用的方式有比如,txt格式、HTML格式、XML格式、JSON格式表現,甚至可以採用二進位制格式;圖片可以用JPG格式表現,也可以用PNG格式表現。
從上圖可以看到,api的表現形式(也就是返回資料格式)為json格式。

3. 狀態

狀態定義了做資源的操作方式。這些操作方式全部定義在http協議裡面,而不再api上表現。客戶端通過四個HTTP動詞,對伺服器端資源進行操作
具體操作:

  • GET(SELECT):從伺服器取出資源(一項或多項)。
  • POST(CREATE):在伺服器新建一個資源。
  • PUT(UPDATE):在伺服器更新資源(客戶端提供完整資源資料)。
  • PATCH(UPDATE):在伺服器更新資源(客戶端提供需要修改的資源資料)。
  • DELETE(DELETE):從伺服器刪除資源。

3、認證機制

我們知道,客戶端通過api可以訪問到資源,但我們還需要對訪問者進行驗證,以用來判斷該使用者的訪問許可權。
常用的認證機制包括 session auth(即通過使用者名稱密碼登入),basic auth,token auth和OAuth,服務開發中常用的認證機制為後三者。
這裡主要介紹一下OAuth。

1. OAuth介紹

OAuth(開放授權)是一個開放的授權標準,允許使用者讓第三方應用訪問該使用者在某一web服務上儲存的私密的資源(如照片,視訊,聯絡人列表),而無需將使用者名稱和密碼提供給第三方應用。

OAuth允許使用者提供一個令牌,而不是使用者名稱和密碼來訪問他們存放在特定服務提供者的資料。每一個令牌授權一個特定的第三方系統(例如,視訊編輯網站)在特定的時段(例如,接下來的2小時內)內訪問特定的資源(例如僅僅是某一相簿中的視訊)。這樣,OAuth讓使用者可以授權第三方網站訪問他們儲存在另外服務提供者的某些特定資訊,而非所有內容。

正是由於OAUTH的嚴謹性和安全性,現在OAUTH已成為RESTful架構風格中最常用的認證機制,和RESTful架構風格一起,成為企業級服務的標配。
目前OAuth已經從OAuth1.0發展到OAuth2.0,但這二者並非平滑過渡升級,OAuth2.0在保證安全性的前提下大大減少了客戶端開發的複雜性。

二 Django REST framework簡介

Django REST framework是一個基於Django實現的一個restful框架,一個十分強大切靈活的工具包,用以構建Web APIs。
Djando REST framework的優點:

  • 線上可視的API
  • 驗證策略涵蓋了OAuth1和OAuth2
  • 同時支援ORM和非ORM資料來源的序列化
  • 支援基於類的檢視

安裝與部署環境

使用pip安裝框架以及所有依賴包

pip install djangorestframework
pip install markdown  # 可以更好的支援可瀏覽的API
pip install django-filter  # 支援過濾

還可以使用clone安裝
git clone [email protected]:encode/django-rest-framework.git
安裝完之後需要在專案的配置檔案的app裡面註冊rest_framework,因為有些地方會用到rest_framework這個app裡面的資料,例如返回資料的模板

INSTALLED_APPS= (
    ...
    'rest_framework',

)

三 Django REST framework簡單流程

首先我們看一個通過Django REST framework實現的一個api的簡單例項

# views.py 首先寫檢視函式
from rest_framework.views import APIView
from rest_framework.response import Response


class TestView(APIView):  # CBV模式的檢視函式

    def get(self, request, *args, **kwargs):
        # 定義get方法
        # 在django-rest-framework中的request被重新封裝了,後續分析原始碼的時候會有具體體現
        return Response('測試api')  # rest-framework的模板對資料進行渲染

# urls.py 定義路由
from django.conf.urls import url
from django.contrib import admin

from app01 import views

urlpatterns = [
    url(r'^user/', views.TestView.as_view())
]

啟動專案,訪問api:

原理分析:

  1. rest_framework重寫了一個APIView的類,這個類是之前django中的view類的派生類,在寫CBV的檢視函式是,讓檢視函式繼承了rest-framework這個APIView類
  2. 在檢視函式中寫具體方法,例如get,port,put,delete,可以使用rest_framework的Response對返回資料進行渲染
  3. 在url的寫法和Django是一樣的
  4. 通過對http://127.0.0.1:8000/user/ 的訪問,可以得到如圖顯示的資料

四 Django REST framework原始碼流程

在第三節我們分析了一個簡單的api實現過程,現在我們主要去分析rest_framework內部對這個url的具體實現過程。

  1. 首先我們訪問http://127.0.0.1:8000/user/ 根據urls.py中的配置,執行views.TestView.as_view()函式
  2. as_view方法是被定義在rest_framework/views.py裡面的一個靜態方法,所以可以通過類名直接呼叫。

  3. 父類的as_view方法是定義在django/views/generic/base.py裡面的View類中的方法。在這個方法中最終會執行cls.dispatch,在第一步中我們知道cls是<class 'app01.views.TestView'>

  4. dispatch是定義在TestView繼承的父類APIView(rest_framework/views.py)裡面的方法。在這個方法裡面,首先通過 request = self.initialize_request(request, *args, **kwargs)這條語句重新封裝了request物件

  5. initialize_request是APIView類裡面的一個方法,重新封裝了request物件,增加了一些屬性資訊

  6. 認證資訊。主要通過APIView類中的get_authenticators(rest_framework/views.py)方法獲取,這個方法會返回一個所有認證物件的列表
    在全域性定義的authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES

  7. 預設的認證配置資訊是在rest_framework/settings.py檔案中定義的

  8. 在rest_framework/authentication.py中定義了幾種認證型別,一般情況我們需要自定義認證類,也可以使用django-oauth-toolkit元件進行認證。

  9. dispatch中的initialize_request方法執行完成之後,還有執行一個重要方法是self.initial(request, *args, **kwargs),這個方法也是APIView類裡的。在這個方法裡面初始化
    被重新封裝的request物件
    實現功能:
    • 版本處理
    • 使用者認證
    • 許可權
    • 訪問頻率限制

  10. 執行APIView裡面的perform_authentication方法,該方法返回request.user,則會呼叫裡面的user方法。在user方法裡面最終呼叫了Request類裡面的_authenticate方法


  11. 執行rest_framework.request.Request類中的_authenticate方法,這個方法會遍歷認證類,並根據認證結果給self.user, self.auth賦值。由於user,和auth都有property屬性,
    所以給賦值的時候先在先執行setter方法


  12. dispatch中的initial方法執行完之後,會繼續判斷request.method並執行method相應的method.

  13. 執行TestView中定義的get方法,返回資料