在以前的 view 中,咱們使用了 APIView 編寫處理數據的邏輯,如前文所講 APIView 直接繼承 View 是一個比較偏底層的類,儘管靈活但須要本身實現不少經常使用功能。DRF 中在 APIView 的基礎上提供了一系列高級類來簡化這些平常操做,好比: ListModelMixin, GenericAPIView 等。
見: https://www.django-rest-framework.org/tutorial/3-class-based-views/ Using mixins 章節。數據庫
Mixins:django
mixin 類提供了 actions 用於實現基礎的 view 功能。注意:這裏的 action 方法並不是 http handler 如:.get(), .post() 等, 而是 create,list, retrieb,update, desdory 這樣的方式是具體的實現更加靈活。api
GenericAPIView:iview
這個類繼承了 APIView,並在此基礎上實現了基礎的 list 和 detail views。在使用 GenericAPIView 時,一般都是與 minxin 類組合使用,好比 ListAPIView 同時繼承了 ListModelMixin 和 GenericAPIView(見後面例子)。
在 generics 庫中,一般也都是這樣的搭配,即:一個 XXXModelMixin + GenericAPIView。 其中GenericAPIView 負責數據部分,好比 queryset 和 serializer,包括 Pagination 等。 ModelMixin 則控制着如何 handle 這些數據 如: list,create, update 等。 經過兩個類的互補來實現了一些特定功能。ide
類屬性:函數
分頁:post
過濾:ui
詳見 https://www.django-rest-framework.org/api-guide/generic-views/#genericapiviewurl
ListModelMixin 例子(ModelMixin 系列中的一個):spa
該類 提供 .list(request, *args, **kwargs) 方法,來實現列出 queryset。若是 queryset 返回 http 結果 200 OK, 表示有數據,則該數據生成的列表能夠用分頁方法進行個性化顯示。
詳見: https://www.django-rest-framework.org/api-guide/generic-views/#listmodelmixin
1 from products.serializers import ProductSerializer 2 from products.models import Product 3 from rest_framework import mixins 4 from rest_framework import generics 5 6 class ProductListView(mixins.ListModelMixin, generics.GenericAPIView): 7 """注意:與 APIView 不一樣的是, queryset 和 serializer 都已經包含在 GenericAPIView 中了,因此在此無需自行作代碼實現 """ 8 queryset = Product.objects.all() 9 serializer_class = ProductSerializer 10 11 def get(self, request, *args, **kwargs): 12 return self.list(request, *args, **kwargs) # ListModelMixin 中包括 list 方法,該方法返回 queryset 做爲 response
def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)
PS: For all of Views (execept viewsets) like GenericAPIView, APIView, ListAPIView ... we must provide/overwirte http methode (get, put, delete etc.)
若是 ProductListView 不須要提供 post 功能,該類能夠更簡單地經過 ListAPIView 來實現,具體以下:
1 class ProductListView(generics.ListAPIView): 2 # 省略以下代碼 3 # def get(self, request, *args, **kwargs): 4 # return self.list(request, *args, **kwargs) 5 6 queryset = Product.objects.all() 7 serializer_class = ProductSerializer
經查閱源碼,ListAPIView 的實現其實與第一個例子的邏輯幾乎如出一轍,只是少了 post 函數,由於 ListAPIView 的功能僅限於展現數據,而並不是對數據進行增長或改動。
ListAPIView extra 知識點:
ListAPIView 通常用於在頁面上列出全部對象詳細信息,這個數據量有可能會相對龐大一些,因此須要考慮在此對輸出頁面進行分頁配置。
在 DRF 中能夠經過 setting.py 一個配置來完成分頁這個複雜的功能。
見: https://www.django-rest-framework.org/api-guide/pagination/ Pagination 部分
在 setting 文件中末尾添加:
1 REST_FRAMEWORK = { 2 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 3 'PAGE_SIZE': 10 4 }
這樣就會對結果進行自動分頁且每頁只顯示 10 個數據對象
若是目前的 Pagination 功能還不知足項目須要,可更深度地自定製分頁功能。詳見 Modify the pagination style 部分。
經過修改 view.py 文件
1 from rest_framework.pagination import PageNumberPagination 2 3 # 設置個性化分頁功能 4 class ProductPagination(PageNumberPagination): 5 page_size = 10 6 page_size_query_param = 'page_size' 7 page_query_param = 'p' # http://127.0.0.1:8000/product/?p=1 改成了 p 而不是原來的 page 8 max_page_size = 100 9 10 class ProductListView(generics.ListAPIView): 11 queryset = Product.objects.all() 12 serializer_class = ProductSerializer 13 pagination_class = ProductPagination # 指向個性化分頁配置類
注:完成以上配置後,則不須要另外對 setting 文件中的 REST_FRAMEWORK 參數進行設置。