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

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

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

定義視圖時,只要視圖繼承了APIView或其子類,就可以使用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相關的知識點。如若文中出現問題,各位大佬多多指點,互相學習。喜歡的關注一個吧!謝謝!