3 Django REST Framework 開發 ---- Generic Views

在以前的 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

類屬性:函數

  • queryset - 用於返回 view 數據庫中須要的對象。
  • serializer_class - 用於作驗證,反序列化 Input,序列化 Output。
  • lookup_field - 搜索字段
  • lokup_url_kwarg - tbd

分頁:post

  • pagination_class - 自定義分頁

過濾:ui

  • filter_backend - 用於過濾 queryset

詳見 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 參數進行設置。

相關文章
相關標籤/搜索