1. 程式人生 > 實用技巧 >Django REST framework (DRF)框架入門之檢視【三】

Django REST framework (DRF)框架入門之檢視【三】

1. 檢視

drf除了在資料序列化部分簡寫程式碼以外,還在檢視中提供了簡寫操作。所以在django原有的django.views.View類基礎上,drf封裝了多個子類出來提供給我們使用。

Django REST framwork 提供的檢視的主要作用:

  • 控制序列化器的執行(檢驗、儲存、轉換資料)
  • 控制資料庫查詢的執行
  • 呼叫請求類和響應類[這兩個類也是由drf幫我們再次擴充套件了一些功能類。]

為了方便我們學習,所以先建立一個子應用req

python manage.py startapp req

1.1. 請求與響應

1.1.1 Request

REST framework 傳入檢視的request物件不再是Django預設的HttpRequest物件,而是REST framework提供的擴充套件了HttpRequest類的Request

類的物件。

REST framework 提供了Parser解析器,在接收到請求後會自動根據Content-Type指明的請求資料型別(如JSON、表單等)將請求資料進行parse解析,解析為類字典[QueryDict]物件儲存到Request物件中。

Request物件的資料是自動根據前端傳送資料的格式進行解析之後的結果。

無論前端傳送的哪種格式的資料,我們都可以以統一的方式讀取資料。

1.1.1.1 常用屬性

1).data

request.data 返回解析之後的請求體資料。類似於Django中標準的request.POSTrequest.FILES屬性,但提供如下特性:

  • 包含了解析之後的檔案和非檔案資料
  • 包含了對POST、PUT、PATCH請求方式解析後的資料
  • 利用了REST framework的parsers解析器,不僅支援表單型別資料,也支援JSON資料
2).query_params

request.query_params與Django標準的request.GET相同,只是更換了更正確的名稱而已。

1.1.2 Response

rest_framework.response.Response

REST framework提供了一個響應類Response,使用該類構造響應物件時,響應的具體資料內容會被轉換(render渲染)成符合前端需求的型別。

REST framework提供了Renderer

渲染器,用來根據請求頭中的Accept(接收資料型別宣告)來自動轉換響應資料到對應格式。如果前端請求中未進行Accept宣告,則會採用預設方式處理響應資料,我們可以通過配置來修改預設響應格式。

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (  # 預設響應渲染類
        'rest_framework.renderers.JSONRenderer',  # json渲染器
        'rest_framework.renderers.BrowsableAPIRenderer',  # 瀏覽API渲染器
    )
}

1.1.2.1 構造方式

Response(data, status=None, template_name=None, headers=None, content_type=None)

data資料不要是render處理之後的資料,只需傳遞python的內建型別資料即可,REST framework會使用renderer渲染器處理data

data不能是複雜結構的資料,如Django的模型類物件,對於這樣的資料我們可以使用Serializer序列化器序列化處理後(轉為了Python字典型別)再傳遞給data引數。

引數說明:

  • data: 為響應準備的序列化處理後的資料;
  • status: 狀態碼,預設200;
  • template_name: 模板名稱,如果使用HTMLRenderer 時需指明;
  • headers: 用於存放響應頭資訊的字典;
  • content_type: 響應資料的Content-Type,通常此引數無需傳遞,REST framework會根據前端所需型別資料來設定該引數。

1.1.2.2 常用屬性

1).data

傳給response物件的序列化後,但尚未render處理的資料

2).status_code

狀態碼的數字

3).content

經過render處理後的響應資料

1.1.2.3 狀態碼

為了方便設定狀態碼,REST framewrok在rest_framework.status模組中提供了常用狀態碼常量。

1)資訊告知 - 1xx
HTTP_100_CONTINUE
HTTP_101_SWITCHING_PROTOCOLS
2)成功 - 2xx
HTTP_200_OK
HTTP_201_CREATED
HTTP_202_ACCEPTED
HTTP_203_NON_AUTHORITATIVE_INFORMATION
HTTP_204_NO_CONTENT
HTTP_205_RESET_CONTENT
HTTP_206_PARTIAL_CONTENT
HTTP_207_MULTI_STATUS
3)重定向 - 3xx
HTTP_300_MULTIPLE_CHOICES
HTTP_301_MOVED_PERMANENTLY
HTTP_302_FOUND
HTTP_303_SEE_OTHER
HTTP_304_NOT_MODIFIED
HTTP_305_USE_PROXY
HTTP_306_RESERVED
HTTP_307_TEMPORARY_REDIRECT
4)客戶端錯誤 - 4xx
HTTP_400_BAD_REQUEST
HTTP_401_UNAUTHORIZED
HTTP_402_PAYMENT_REQUIRED
HTTP_403_FORBIDDEN
HTTP_404_NOT_FOUND
HTTP_405_METHOD_NOT_ALLOWED
HTTP_406_NOT_ACCEPTABLE
HTTP_407_PROXY_AUTHENTICATION_REQUIRED
HTTP_408_REQUEST_TIMEOUT
HTTP_409_CONFLICT
HTTP_410_GONE
HTTP_411_LENGTH_REQUIRED
HTTP_412_PRECONDITION_FAILED
HTTP_413_REQUEST_ENTITY_TOO_LARGE
HTTP_414_REQUEST_URI_TOO_LONG
HTTP_415_UNSUPPORTED_MEDIA_TYPE
HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE
HTTP_417_EXPECTATION_FAILED
HTTP_422_UNPROCESSABLE_ENTITY
HTTP_423_LOCKED
HTTP_424_FAILED_DEPENDENCY
HTTP_428_PRECONDITION_REQUIRED
HTTP_429_TOO_MANY_REQUESTS
HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE
HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS
5)伺服器錯誤 - 5xx
HTTP_500_INTERNAL_SERVER_ERROR
HTTP_501_NOT_IMPLEMENTED
HTTP_502_BAD_GATEWAY
HTTP_503_SERVICE_UNAVAILABLE
HTTP_504_GATEWAY_TIMEOUT
HTTP_505_HTTP_VERSION_NOT_SUPPORTED
HTTP_507_INSUFFICIENT_STORAGE
HTTP_511_NETWORK_AUTHENTICATION_REQUIRED

1.2 檢視

REST framework 提供了眾多的通用檢視基類與擴充套件類,以簡化檢視的編寫。

1.2.1 2個檢視基類

1.2.1.1 APIView

rest_framework.views.APIView

APIView是REST framework提供的所有檢視的基類,繼承自Django的View父類。

APIViewView的不同之處在於:

  • 傳入到檢視方法中的是REST framework的Request物件,而不是Django的HttpRequeset物件;
  • 檢視方法可以返回REST framework的Response物件,檢視會為響應資料設定(render)符合前端要求的格式;
  • 任何APIException異常都會被捕獲到,並且處理成合適的響應資訊;
  • 在進行dispatch()分發前,會對請求進行身份認證、許可權檢查、流量控制。

支援定義的屬性

  • authentication_classes 列表或元祖,身份認證類
  • permissoin_classes 列表或元祖,許可權檢查類
  • throttle_classes 列表或元祖,流量控制類

APIView中仍以常規的類檢視定義方法來實現get() 、post() 或者其他請求方式的方法。

舉例:

from rest_framework.views import APIView
from rest_framework.response import Response

# url(r'^books/$', views.BookListView.as_view()),
class BookListView(APIView):
    def get(self, request):
        books = BookInfo.objects.all()
        serializer = BookInfoSerializer(books, many=True)
        return Response(serializer.data)

1.2.1.2 GenericAPIView[通用檢視類]

rest_framework.generics.GenericAPIView

繼承自APIVIew主要增加了操作序列化器和資料庫查詢的方法,作用是為下面Mixin擴充套件類的執行提供方法支援。通常在使用時,可搭配一個或多個Mixin擴充套件類。

提供的關於序列化器使用的屬性與方法

  • 屬性:

    • serializer_class 指明檢視使用的序列化器
  • 方法:

    • get_serializer_class(self)

      當出現一個檢視類中呼叫多個序列化器時,那麼可以通過條件判斷在get_serializer_class方法中通過返回不同的序列化器類名就可以讓檢視方法執行不同的序列化器物件了。

      返回序列化器類,預設返回serializer_class,可以重寫,例如:

      def get_serializer_class(self):
          if self.request.user.is_staff:
              return FullAccountSerializer
          return BasicAccountSerializer
      
    • get_serializer(self, args, *kwargs)

      返回序列化器物件,主要用來提供給Mixin擴充套件類使用,如果我們在檢視中想要獲取序列化器物件,也可以直接呼叫此方法。

      注意,該方法在提供序列化器物件的時候,會向序列化器物件的context屬性補充三個資料:request、format、view,這三個資料物件可以在定義序列化器時使用。

      • request 當前檢視的請求物件
      • view 當前請求的類檢視物件
      • format 當前請求期望返回的資料格式

提供的關於資料庫查詢的屬性與方法

  • 屬性:

    • queryset 指明使用的資料查詢集
  • 方法:

    • get_queryset(self)

      返回檢視使用的查詢集,主要用來提供給Mixin擴充套件類使用,是列表檢視與詳情檢視獲取資料的基礎,預設返回queryset屬性,可以重寫,例如:

      def get_queryset(self):
          user = self.request.user
          return user.accounts.all()
      
    • get_object(self)

      返回詳情檢視所需的模型類資料物件,主要用來提供給Mixin擴充套件類使用。

      在試圖中可以呼叫該方法獲取詳情資訊的模型類物件。

      若詳情訪問的模型類物件不存在,會返回404。

      該方法會預設使用APIView提供的check_object_permissions方法檢查當前物件是否有許可權被訪問。

      舉例:

      # url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
      class BookDetailView(GenericAPIView):
          queryset = BookInfo.objects.all()
          serializer_class = BookInfoSerializer
      
          def get(self, request, pk):
              book = self.get_object() # get_object()方法根據pk引數查詢queryset中的資料物件
              serializer = self.get_serializer(book)
              return Response(serializer.data)
      

其他可以設定的屬性

  • pagination_class 指明分頁控制類
  • filter_backends 指明過濾控制後端