Djangorestframework以前戲

咱們首先來看django的請求生命週期html

-先進入實現了wsgi協議的web服務器----》進入django---》中間件---》路由---》視圖---》取模板,取數據,用數據渲染模板---》返回模板的字符串---》在瀏覽器上看到頁面了前端

這裏咱們不妨來看看wsgire協議和CGI協議python

 

 

CGI是比較原始的開發動態網站的方式。你能夠想象一下,一個網站的動態內容確定是程序生成的,光是靜態的html頁面沒法達到這個效果。那麼,這個程序就須要接受客戶端的請求,而後進行相應處理,再返回給客戶端,客戶端和服務端的通訊固然是經過HTTP協議。而後咱們會發現,這個程序在處理客戶端請求的時候,大部分時候會進行不少重複的工做,好比說HTTP請求的解析。也就是說,你的程序須要解析HTTP請求,個人程序也須要解析。因而爲了DRY原則,Web服務器誕生了。(如下所說的都是CGI的工做模式)web

因而Web服務器能夠解析這個HTTP請求,而後把這個請求的各類參數寫進進程的環境變量,好比REQUEST_METHOD,PATH_INFO之類的。以後呢,服務器會調用相應的程序來處理這個請求,這個程序也就是咱們所要寫的CGI程序了。它會負責生成動態內容,而後返回給服務器,再由服務器轉交給客戶端。服務器和CGI程序之間通訊,通常是經過進程的環境變量和管道。這樣作雖然很清晰,但缺點就是每次有請求,服務器都會fork and exec,每次都會有一個新的進程產生,開銷仍是比較大的。緣由在與CGI程序是一個獨立的程序,它是能夠獨立運行的(在提供HTTP請求的狀況下),它能夠用幾乎全部語言來寫,包括perl,c,lua,python等等。因此對於一個程序,服務器只能以fork and exec的方式來調用它了。django

WSGI是Web Server Gateway Interface的縮寫。以層的角度來看,WSGI所在層的位置低於CGI。但與CGI不一樣的是WSGI具備很強的伸縮性且能運行於多線程或多進程的環境下,這是由於WSGI只是一份標準並無定義如何去實現。實際上WSGI並不是CGI,由於其位於web應用程序與web服務器之間,而web服務器能夠是CGI,mod_python(注:現一般使用mod_wsgi代替),FastCGI或者是一個定義了WSGI標準的web服務器就像python標準庫提供的獨立WSGI服務器稱爲wsgiref。json

WSGI裏的組件分爲『Server』,『Middleware』和『Application』三種,其中的『Middleware』是『設計模式』裏的Decorator(裝飾器)。設計模式

WSGI規範在PEP-333裏講得很詳細:PEP 0333 -- Python Web Server Gateway Interface v1.0 ,但我以爲比理解規範更重要的,是理解其設計目的和工做原理。api

WSGI規範寫得有點繞,之因此繞, 主要緣由多是沒有用『類型提示(Type Hints)』,若是用強類型OOP語言的那種『Interface』和『UML』來解釋會清晰不少。瀏覽器

實現了wsgi 協議對應的web服務器就是uwsgi,相似Java中的tomcat 。有興趣的話能夠讀一下tomcat原理https://blog.csdn.net/qq_38977097/article/details/81089172tomcat

 

CBV 源碼分析

原生django的視圖層能夠分爲兩類 FBV和CBV,因爲djangorestframework只可以由FBV完成,因此簡單來看一下FBV的源碼。

 

在FBV視圖裏面 ,咱們的路由是類加as_view(),可是咱們寫的類並無這個屬性或方法 ,實際上是用了父類(view)的

as_view的方法,

不難看出這就是一個閉包函數,傳參給view函數,這時候會走view裏面的self.dispatch方法,因爲對象沒有,只可以走父類(view)的dispatch方法

 

 dispatch方法只是利用了反射請求方法來分發函數,至此咱們對CBV源碼有了一個簡單認識。看懂這個將對咱們理解後面的drf有極大地幫助。

 restful規範

 

  • REST與技術無關,表明的是一種軟件架構風格,REST是Representational State Transfer的簡稱,中文翻譯爲「表徵狀態轉移」
  • REST從資源的角度類審視整個網絡,它將分佈在網絡中某個節點的資源經過URL進行標識,客戶端應用經過URL來獲取資源的表徵,得到這些表徵導致這些應用轉變狀態
  • REST與技術無關,表明的是一種軟件架構風格,REST是Representational State Transfer的簡稱,中文翻譯爲「表徵狀態轉移」
  • 全部的數據,不過是經過網絡獲取的仍是操做(增刪改查)的數據,都是資源,將一切數據視爲資源是REST區別與其餘架構風格的最本質屬性
  • 對於REST這種面向資源的架構風格,有人提出一種全新的結構理念,即:面向資源架構(ROA:Resource Oriented Architecture)

 

 

下面咱們逐條來分析一下restful規範的設計
API與用戶的通訊協議,老是使用HTTPs協議

2  域名有區分

-https://api.example.com
-https://example.org/api/

3 版本
  能夠放在路徑中
  能夠放在請求頭中

4 路徑,視網絡上任何東西都是資源,均使用名詞表示
  https://api.example.com/v1/zoos

5 經過method 區分是什麼操做
  get表示獲取
  post表示新增
  delete表示刪除
  patch/put 表示修改

6 過濾,經過在url上傳參的形式傳遞搜索條件

7 狀態碼
{"status_code":100}

8 錯誤處理,應返回錯誤信息
{"status_code":100,'msg':'登陸成功'}
{"status_code":101,'msg':'用戶名錯誤'}

9 返回結果,針對不一樣操做,服務器向用戶返回的結果
  get獲取全部資源/get獲取一個資源
  127.0.0.1/api/vi/books 獲取全部圖書
  {"status_code":100,'msg':'獲取成功',data:[{},{}]}
  127.0.0.1/api/vi/books/3 獲取id爲3的圖書
  {"status_code":100,'msg':'獲取成功',data:{name:xx,....}}
  新增數據,把新增的數據再返回
  修改了數據,返回完整的資源對象
   刪除數據,返回一個空文檔
10 返回結果中提供連接

{"link": {
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}

 

基於原生django開發restful的接口

from django.views import View
from app01 import models
class APIView(View):

    def dispatch(self, request, *args, **kwargs):
        #寫一些頻率控制的東西
        ret = super().dispatch(request, *args, **kwargs)
        return ret

class Test(APIView):
    # http_method_names=['get']
    def get(self,request, *args, **kwargs):
        return HttpResponse('ok')

 

djangorestframework

安裝下載:pip install djangorestframework

 

from rest_framework.views import  APIView
class Books(APIView):
    def get(self,request):
        #request是被封裝後的request,原生的request在request._request
        #若是想用原生requset中的屬性,仍是原來的用法,由於Request重寫了__getattr__方法
        # 原生django只能處理urlencoded和formdata編碼,若是是json格式,原生django是不能處理的,須要本身從body中取出來自行處理
        # request.data 無論前端傳數據的編碼格式是urlencoded,formdata或者是json,都從裏面取值
        # request.data
        #request.query_params  是原來django原生的GET中的數據
        #self.FILES  就是上傳的文件
        dic={'name':'lqz','age':30,'height':178,'wife':['liuyifei','dilireba','egon']}
        return JsonResponse(dic)

 

#在settings.py文件中添加rest_framework,這就是django的一個app。

INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'app01.apps.App01Config', 'rest_framework' ]

 

 

咱們對drf的源碼分析,首先咱們定義一個類,這個類繼承的事APIView
繼承了APIView 以後:
  1 全部的請求都沒有csrf的認證了
  2 在APIView中as_view本質仍是調用了父類的as_view(View的as_view)
  3 as_view中調用dispatch -----》這個dispatch是APIView的dispatch

 

 

APIVIew的dispatch方法:
  1 對原生request對象作了一層包裝(面向對象的封裝),之後再用的request對象都新的request對象
  2 在APIView中self.initial(request, *args, **kwargs),裏面有頻率控制,權限控制和認證相關
  3 根據請求方法執行我們寫的視圖類中的相應方法

 


這個時候視圖類中方法的request對象,已經變成了封裝後的request
Request類:
  1 原生的request是self._request
  2 取以post形式提交的數據,從request.data中取(urlencoded,formdata,json格式)
  3 query_params 就是原生request的GET的數據
  4 上傳的文件是從FILES中取
  5 (重點)其餘的屬性,直接request.屬性名(由於重寫了__getattr__方法)

相關文章
相關標籤/搜索