Django Rest Framework 視圖集

視圖集ViewSet

視圖集的繼承關(guān)系
視圖集類繼承關(guān)系.png
兩個基本視圖集
視圖集 繼承自
Viewset APIView,ViewSetMixin
GenricViewset GenericAPIView,ViewSetMixin
  • ViewSet
    • 在ViewSet中,沒有提供任何動作action方法,需自己實現(xiàn)動作action( list() 、create() 等)
    • 因為繼承自ViewSetMixin,實現(xiàn)了將請求方式和action動作在as_view中進(jìn)行映射,鍵值對中,值可以相同,鍵必須不同
      as_view({'請求方式1':'action動作1','請求方式2':'action動作2',})
  • GenricViewSet
class BooksViewSet(ViewSet):
    def list(self, request):
        #獲取所有數(shù)據(jù)
        books = BookInfo.objects.all()
        ser = BookSerializers(books, many=True)
        return Response(ser.data)

    def create(self, request):
        #保存數(shù)據(jù)
        data = request.data
        ser = BookSerializers(data=data)
        ser.is_valid(raise_exception=True)
        ser.save()
        return Response(ser.data)

    def last(self, request):
        #返回最后一本圖書信息
        book = BookInfo.objects.last()
        ser = BookSerializers(book)
        return Response(ser.data)

    def show(self, request, pk):
        #獲取指定數(shù)據(jù)
        book = BookInfo.objects.get(id=pk)
        ser = BookSerializers(book)
        return Response(ser.data)
兩個擴(kuò)展視圖集
擴(kuò)展視圖集 繼承自
ModelViewset GenricViewset,五個擴(kuò)展類
ReadOnlyModelViewSet GenricViewset,ListModelMixin,RetrieveModelMixin
  • ModelViewset
    • 繼承自GenericAPIVIew、ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin
  • ReadOnlyModelViewSet
    • 參與序列化返回,所以繼承自查詢單個數(shù)據(jù)和查詢所有數(shù)據(jù)的擴(kuò)展類
#定義一個分頁
class PageNum(PageNumberPagination):
    page_size_query_param = 'page_size'  #指定控制頁面展示數(shù)量的參數(shù)
    max_page_size = 8  #最大返回多少條數(shù)據(jù)

class BooksModelViewSet(ModelViewSet):
    serializer_class = BookSerializers
    queryset = BookInfo.objects.all()
    #局部認(rèn)證屬性
    # authentication_classes = [BasicAuthentication, SessionAuthentication]
    #局部權(quán)限屬性
    # permission_classes = [IsAuthenticated]
    #局部限流屬性
    # throttle_classes = [UserRateThrottle]
    #對視圖進(jìn)行限流命名, 在setting.py中進(jìn)行限流次數(shù)的指定
    # throttle_scope = 'shows'
    #過濾字段指定
    # filter_fields = ('btitle', 'bread')
    # #排序過濾
    # #指定過濾的類方法
    # filter_backends = [OrderingFilter]
    # #針對排序的字段定義
    # ordering_fields = ['id', 'bread']
    #局部配置 分頁屬性
    # pagination_class = PageNum

    @action(methods=['get'], detail=True)
    def show(self, request, pk):
        #手動拋出一個異常
        # raise DataError
        #獲取指定數(shù)據(jù)
        book = self.get_object()
        ser = self.get_serializer(book)
        return Response(ser.data)
視圖集自定義action動作

在視圖集中,除了默認(rèn)的動作(list() 提供一組數(shù)據(jù),retrieve() 提供單個數(shù)據(jù),create() 創(chuàng)建數(shù)據(jù),update() 保存數(shù)據(jù),destory() 刪除數(shù)據(jù))外,可以自定義動作

  • 添加自定義動作時,需要rest_framework.decorators.action裝飾器
  • 在自定義動作方法上,添加@action(),接收兩個參數(shù)
    • methods,該action支持的請求方式,列表傳遞
    • detail,action中要處理的是否是視圖資源的對象(即是否通過url路徑獲取主鍵)
      • True 表示使用通過URL獲取的主鍵對應(yīng)的數(shù)據(jù)對象
      • False 表示不使用URL獲取主鍵

路由Router

SimpleRouter
  1. 創(chuàng)建router,并注冊視圖集
  • register(prefix, viewset, base_name)
    • prefix 該視圖集的路由前綴
    • viewset 視圖集
    • base_name 路由名稱的前綴
from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'books', BookInfoViewSet, base_name='book')
  1. 添加路由數(shù)據(jù)
  • 在注冊之后,urlpatterns += router.urls
  • 直接在urlpatterns中includerouter.url
    • url(r'^', include(router.urls))
  1. 視圖集中使用裝飾器@action,在視圖類內(nèi)自定義的方法上添加自動生成路由
  • @action(methods=['get'], detail=False)
    • detail為False,生成的路由中不會有正則匹配(方法中不接收參數(shù))
    • detail為True,生成的路由中有正則匹配(方法中接收參數(shù))
DefaultRouter

DefaultRouter會多附帶一個默認(rèn)的API根視圖,返回一個包含所有列表視圖的超鏈接響應(yīng)數(shù)據(jù)

因為視圖集繼承自ViewSetMixin,才有action屬性,裝飾器和自動生成路由的方法

認(rèn)證,權(quán)限和限流屬性(APIView)

  • authentication_classes認(rèn)證屬性
    • 全局認(rèn)證,在settings.py的REST_FRAMEWORK中定義 'DEFAULT_AUTHENTICATION_CLASSES'
    • 局部認(rèn)證,在類視圖中定義authentication_classes = (SessionAuthentication, BasicAuthentication)
  • permission_classes 權(quán)限認(rèn)證
    • 權(quán)限控制可以限制用戶對于視圖的訪問和對于具體數(shù)據(jù)對象的訪問
      • 在執(zhí)行視圖的dispatch()方法前,會先進(jìn)行視圖訪問權(quán)限的判斷
      • 在通過get_object()獲取具體對象時,會進(jìn)行對象訪問權(quán)限的判斷
    • 提供的權(quán)限
      • AllowAny 允許所有用戶
      • IsAuthenticated 僅通過認(rèn)證的用戶
      • IsAdminUser 僅管理員用戶
      • IsAuthenticatedOrReadOnly 認(rèn)證的用戶可以完全操作,否則只能get讀取
    • 全局配置,在settings.py的REST_FRAMEWORK中定義 'DEFAULT_PERMISSION_CLASSES',
    • 局部配置,在類視圖中定義permission_classes = (IsAuthenticated,)
  • throttle_classes限流屬性
    • 全局配置,在settings.py的REST_FRAMEWORK中定義DEFAULT_THROTTLE_CLASSES (限流類)和 DEFAULT_THROTTLE_RATES(限流周期)
      • 可選限流類
        • AnonRateThrottle,限制所有匿名未認(rèn)證用戶,DEFAULT_THROTTLE_RATES['anon'] 來設(shè)置頻次
        • UserRateThrottle,限制認(rèn)證用戶,DEFAULT_THROTTLE_RATES['user'] 來設(shè)置頻次
        • ScopedRateThrottle,限制用戶對于每個視圖的訪問頻次,在視圖類中用throttle_scope起別名,在settings.py中對別名進(jìn)行頻次設(shè)置
    • 局部配置,在類視圖中定義throttle_classess=(UserRateThrottle,)

過濾與排序?qū)傩?/h3>
  • 過濾
    • 安裝django-filter
    pip insall django-filter
    
    • 將django-filter在settings.py中注冊應(yīng)用
    • 在settings.py中的REST_FRAMEWORK,定義'DEFAULT_FILTER_BACKENDS'
    • 在視圖中添加filter_fields屬性,指定可以過濾的字段
    • 在瀏覽器進(jìn)行訪問時,?字段=查詢內(nèi)容
  • 排序
    • 在試圖類中設(shè)置filter_backends,使用rest_framework.filters.OrderingFilter過濾器,REST framework會在請求的查詢字符串參數(shù)中檢查是否包含了ordering參數(shù),如果包含了ordering參數(shù),則按照ordering參數(shù)指明的排序字段對數(shù)據(jù)集進(jìn)行排序。
    • 前端可以傳遞的ordering參數(shù)的可選字段值需要在ordering_fields中指明。
    • 不用在settings.py中做任何配置
    • 瀏覽器訪問時,通過?ordering=字段,從小到大,-字段,從大到小
filter_backends = [OrderingFilter]
    ordering_fields = ('id', 'bread', 'bpub_date')
  • 過濾和排序不能同時使用

分頁,異常處理和自動生成接口文檔

  • 分頁
    • 全局配置
      REST_FRAMEWORK = {
          'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
          'PAGE_SIZE': 100  # 每頁數(shù)目
      }
      
    • 局部配置
      -自定義Pagination類,為視圖添加分頁行為
      class LargeResultsSetPagination(PageNumberPagination):
          page_size = 1000
          page_size_query_param = 'page_size'
          max_page_size = 10000
      class BookDetailView(RetrieveAPIView):
          queryset = BookInfo.objects.all()
          serializer_class = BookInfoSerializer
          pagination_class = LargeResultsSetPagination
      
      • 可選分頁器
        page_size 每頁數(shù)目
        page_query_param 前端發(fā)送的頁數(shù)關(guān)鍵字名,默認(rèn)為"page"
        page_size_query_param 前端發(fā)送的每頁數(shù)目關(guān)鍵字名,默認(rèn)為None
        max_page_size 前端最多能設(shè)置的每頁數(shù)量
        
        from rest_framework.pagination import PageNumberPagination
        
        class StandardPageNumberPagination(PageNumberPagination):
            page_size_query_param = 'page_size'
            max_page_size = 10
        
        class BookListView(ListAPIView):
            queryset = BookInfo.objects.all().order_by('id')
            serializer_class = BookInfoSerializer
            pagination_class = StandardPageNumberPagination
        
        # 127.0.0.1/books/?page=1&page_size=2
        
        default_limit 默認(rèn)限制,默認(rèn)值與PAGE_SIZE設(shè)置一直
        limit_query_param limit參數(shù)名,默認(rèn)'limit'
        offset_query_param offset參數(shù)名,默認(rèn)'offset'
        max_limit 最大limit限制,默認(rèn)None
        
        from rest_framework.pagination import LimitOffsetPagination
        class BookListView(ListAPIView):
            queryset = BookInfo.objects.all().order_by('id')
            serializer_class = BookInfoSerializer
            pagination_class = LimitOffsetPagination
        
        # 127.0.0.1:8000/books/?offset=3&limit=2
        
  • 異常處理
    • 自定義異常處理
      #在類視圖方法中先手動拋出異常
      
      #定義異常處理方法
      from rest_framework.views import exception_handler as drf_exception_handler
      
      def exception_handler(exc, context):
          # 先調(diào)用REST framework默認(rèn)的異常處理方法獲得標(biāo)準(zhǔn)錯誤響應(yīng)對象
          response = drf_exception_handler(exc, context)
      
          # 在此處補充自定義的異常處理
          if response is None:
              view = context['view']
              if isinstance(exc, DataError):
                  print('[%s]: %s' % (view, exc))
                  response = Response({'detail': '服務(wù)器內(nèi)部錯誤'},
                           status=status.HTTP_507_INSUFFICIENT_STORAGE)
      
          return response
      
      #在配置文件中聲明
      REST_FRAMEWORK = {
          'EXCEPTION_HANDLER': 'book.utils.exception_handler'
      }
      
  • 自動生成接口文檔
    • 接口文檔以網(wǎng)頁的方式呈現(xiàn),自動接口文檔能生成的是繼承自APIView及其子類的視圖

    • 安裝依賴

      pip install coreapi

    • 設(shè)置接口文檔訪問路徑

      • 在總路由中添加接口文檔路徑
      • 文檔路由對應(yīng)的視圖配置為rest_framework.documentation.include_docs_urls
      from rest_framework.documentation import include_docs_urls
      
      urlpatterns = [
          ...
          url(r'^docs/', include_docs_urls(title='My API title'))
      ]
      
    • 文檔描述說明的定義位置

      • 單一方法的視圖,可直接使用類視圖的文檔字符串

        class BookListView(generics.ListAPIView):
            """
            返回所有圖書信息.
            """
        
      • 包含多個方法的視圖,在類視圖的文檔字符串中,分開方法定義

        class BookListCreateView(generics.ListCreateAPIView):
            """
            get:
            返回所有圖書信息.
            post:
            新建圖書.
            """
        
      • 對于視圖集ViewSet,仍在類視圖的文檔字符串中分開定義,但是應(yīng)使用action名稱區(qū)分

        class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
            """
            list:
            返回圖書列表數(shù)據(jù)
            retrieve:
            返回圖書詳情數(shù)據(jù)
            latest:
            返回最新的圖書數(shù)據(jù)
            read:
            修改圖書的閱讀量
            """
        
    • 訪問接口文檔網(wǎng)頁

      • 瀏覽器訪問 127.0.0.1:8000/docs/,即可看到自動生成的接口文檔
      • 視圖集ViewSet中的retrieve名稱,在接口文檔網(wǎng)站中叫做read
      • 參數(shù)的Description需要在模型類或序列化器類的字段中以help_text選項定義
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容