DRF框架快速構建認證、權限、限流、過濾、排序和分頁等功能

前面文章講解有關DRF框架的知識,使用DRF框架可以快速的進行序列化和反序列化,

大大提高REST API的開發速度。今天我們來講講DRF框架中如何快速的進行認證、權限、限流、過濾、排序和分頁。

定義視圖時,只要視圖繼承了APIView或其子類,就可以使用DRF框架的認證、權限和限流功能。

DRF框架快速構建認證、權限、限流、過濾、排序和分頁等功能

DRF框架的過濾、排序和分頁功能,僅針對使用ListModelMixin中的list方法列表數據的API接口起作用。

認證Authentication

  • DRF框架默認在rest_framework.settings文件中設置全局認證方案有兩種:session認證和基本認證
  • <code>DEFAULTS = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication', # sesssion認證
    'rest_framework.authentication.BasicAuthentication' # 基本認證
    )
    }/<code>
  • 可以在settings.py配置文件中修改DRF框架默認全局認證方案
  • <code>REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
    'rest_framework.authentication.SessionAuthentication',
    )
    }/<code>
  • 也可以在指定視圖中通過authentication_classes設置視圖的認證方案
  • <code>    # 指定當前視圖自己的認證方案,不再使用全局認證方案
    authentication_classess = [SessionAuthentication]/<code>

    權限Permissions

    DRF框架提供了四個權限控制類:

    • AllowAny 允許所有用戶
    • IsAuthenticated 僅通過認證的用戶
    • IsAdminUser 僅管理員用戶
    • IsAuthenticatedOrReadOnly 認證的用戶可以完全操作,否則只能get讀取

    DRF框架默認在rest_framework.settings文件中進行了全局權限控制方案的設置:

    <code>DEFAULTS = {
    'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.AllowAny', # 允許所有人
    )
    }/<code>
  • 可以在settings.py配置文件中修改DRF框架默認權限控制方案
  • <code>REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
    'rest_framework.permissions.IsAuthenticated', # 允許認證用戶
    )
    }/<code>
  • 也可以在指定視圖中通過permission_classes設置視圖的權限控制方案
  • <code>    # 指定當前視圖自己的權限控制方案,不再使用全局權限控制方案
    permission_classes = [IsAuthenticated]/<code>

    自定義權限控制類可以自定義權限控制類,需繼承rest_framework.permissions.BasePermission父類,並實現以下兩個任何一個方法或全部。

    <code>class MyPermission(BasePermission):
    def has_permission(self, request, view):
    """判斷對使用此權限類的視圖是否有訪問權限"""

    # 任何用戶對使用此權限類的視圖都沒有訪問權限
    return True

    def has_object_permission(self, request, view, obj):
    """判斷對使用此權限類視圖某個數據對象是否有訪問權限"""
    # 需求: 對id為1,3的數據對象有訪問權限
    if obj.id in (1, 3):
    return True
    return False

    class BookInfoViewSet(ReadOnlyModelViewSet):
    # 指定當前視圖所使用的查詢集
    queryset = BookInfo.objects.all()
    # 指定當前視圖所使用的序列化器類
    serializer_class = BookInfoSerializer
    # 使用自定義的權限控制類
    permission_classes = [MyPermission]/<code>

    限流Throttling

    DRF框架默認沒有進行全侷限流設置,可以在settings.py配置文件中,使用DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES進行全局配置。

    可選限流類

    1) AnonRateThrottle

    限制所有匿名未認證用戶,使用IP區分用戶。

    使用DEFAULT_THROTTLE_RATES['anon'] 來設置頻次

    2)UserRateThrottle

    限制認證用戶,使用user id來區分。

    使用DEFAULT_THROTTLE_RATES['user'] 來設置頻次

    3)ScopedRateThrottle

    限制用戶對於每個視圖的訪問頻次,使用ip或user_id

    分別限流設置

  • 指定限流類為AnonRateThrottle和UserRateThrottle
  • <code>REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
    # 針對未登錄(匿名)用戶的限流控制類
    'rest_framework.throttling.AnonRateThrottle',
    # 針對登錄(認證)用戶的限流控制類
    'rest_framework.throttling.UserRateThrottle'
    ),
    # 指定限流頻次
    'DEFAULT_THROTTLE_RATES': {
    # 認證用戶的限流頻次
    'user': '5/minute',
    # 匿名用戶的限流頻次
    'anon': '3/minute',
    },
    }/<code>
  • anon指定匿名用戶的限流頻次,user指定認證用戶的限流頻次
  • 也可以在具體視圖中通過throttle_classess屬性來配置
  • <code>from rest_framework.throttling import UserRateThrottle
    from rest_framework.views import APIView

    class ExampleView(APIView):

    throttle_classes = [AnonRateThrottle]
    .../<code>

    統一限流設置

  • 指定限流類為ScopedRateThrottle,並定義限流頻次選擇項
  • <code>REST_FRAMEWORK = {
    # 針對匿名用戶和認證用戶進行統一的限流控制
    'DEFAULT_THROTTLE_CLASSES': (
    'rest_framework.throttling.ScopedRateThrottle',
    ),

    # 指定限流頻次選擇項
    'DEFAULT_THROTTLE_RATES': {
    'upload': '3/minute',
    'contacts': '5/minute'
    },
    }/<code>
  • 在視圖中通過throttle_scope指定視圖採用的限流頻次選擇項
  • <code>class ContactListView(APIView):
    # 指定當前視圖限流時使用的限流頻次選擇項
    throttle_scope = 'contacts'
    .../<code>

    過濾Filtering

    1)對於列表數據可能需要根據字段進行過濾,可以通過添加django-fitlter擴展來增強支持。

    <code>pip install django-filter/<code>

    2)在配置文件中設置過濾後端

    <code>INSTALLED_APPS = [ 

    ...
    'django_filters', # 需要註冊應用
    ]

    REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),
    }
    /<code>

    3)在視圖中添加filter_fields屬性指定過濾字段

    <code>class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    # 指定過濾字段
    filter_fields = ('btitle', 'bread')

    # http://127.0.0.1:8000/books/?btitle=西遊記/<code>

    排序Ordering

    對於列表數據,REST framework提供了OrderingFilter過濾器來幫助我們快速指明數據按照指定字段進行排序。

    1)在類視圖中設置filter_backends,使用rest_framework.filters.OrderingFilter過濾器

    2)在類視圖中設置ordering_fields指定排序字段

    如:

    <code>class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    # 排序
    filter_backends = [OrderingFilter]
    # 指定排序字段
    ordering_fields = ('id', 'bread', 'bpub_date')
    /<code>

    3)請求API接口時,使用?ordering=指定排序方式,REST framework會按照ordering參數指明的排序字段對數據集進行排序。

    <code>http://127.0.0.1:8000/books/?ordering=-bread/<code>

    分頁Pagination

    1. 全局分頁設置

    可以在配置文件中設置全局分頁類,如:

    <code>REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': '',
    'PAGE_SIZE': ''
    }
    /<code>

    可選分頁類如下:

    1) PageNumberPagination

    前端訪問網址形式:

    <code>GET  http://api.example.org/books/?page=4
    /<code>

    2)LimitOffsetPagination

    前端訪問網址形式:

    <code>GET http://api.example.org/books/?offset=10&limit=40
    /<code>

    如:

    <code>REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 5 # 頁容量

    }
    /<code>

    2. 指定視圖關閉分頁

    設置了全局分頁之後,如果某列表視圖需要關閉分頁,只需在視圖中指定:

    <code># 關閉分頁
    pagination_class = None
    /<code>

    3. 自定義分頁類

    可以自定義分頁類,在視圖中通過pagination_class屬性指定視圖使用的分頁類。

    1)自定義分頁類

    <code>class StandardResultPagination(PageNumberPagination):
    # 指定分頁的默認頁容量
    page_size = 3
    # 指定獲取分頁數據時,指定頁容量參數的名稱
    page_size_query_param = 'page_size'
    # 指定分頁時的最大頁容量
    max_page_size = 5
    /<code>

    2)指定視圖所使用的分頁類

    <code>class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    # 指定當前視圖所使用的分頁類
    pagination_class = StandardResultPagination
    /<code>

    3)通過http://api.example.org/books/?page=&page_size= 進行訪問

    異常處理 Exceptions

    在定義視圖接口時,當繼承了APIView或其子類之後,視圖中如果出現未處理的異常,默認都會調用DRF框架的默認異常處理函數進行處理。

    1. 默認異常處理

    DRF框架的默認異常處理設置如下:

    <code>REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
    }
    /<code>

    注:默認使用rest_framework.views模塊下的exception_handler函數進行異常處理

    exception_handler函數可以處理以下異常,處理之後,會給客戶端返回對應的響應:

    • APIException 所有異常的父類
    • ParseError 解析錯誤
    • AuthenticationFailed 認證失敗
    • NotAuthenticated 尚未認證
    • PermissionDenied 權限決絕
    • NotFound 未找到
    • MethodNotAllowed 請求方式不支持
    • NotAcceptable 要獲取的數據格式不支持
    • Throttled 超過限流次數
    • ValidationError 校驗失敗
    • Http404 資源不存在

    2. 自定義異常處理

    可以自定義異常處理函數,在DRF框架默認異常處理函數的基礎上,添加一些其他的異常處理,比如數據庫處理。

    1)自定義異常處理函數

    <code>from rest_framework.views import exception_handler as drf_exception_handler
    from rest_framework import status
    from django.db import DatabaseError

    def exception_handler(exc, context):
    # 先調用DRF框架的默認異常處理函數
    response = drf_exception_handler(exc, context)

    if response is None:
    # 補充數據庫的異常處理
    if isinstance(exc, DatabaseError):
    response = Response({'detail': '數據庫錯誤'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response
    /<code>

    2)在settings.py配置文件中修改DRF框架的異常處理函數

    <code>REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'booktest.utils.exceptions.exception_handler'
    }/<code>

    以上就是對DRF框架中認證、權限、限流、過濾、排序、分頁和異常處理等功能的講解,根據實際需求可進行參考選擇。

    作者簡介:Python菜鳥工程師,將在接下來的一段時間內與大家分享一些與Python相關的知識點。如若文中出現問題,各位大佬多多指點,互相學習。喜歡的關注一個吧!謝謝!


    分享到:


    相關文章: