1. 程式人生 > >Rest Framework 中的一些方法

Rest Framework 中的一些方法

認證Authentication

可以在配置檔案中配置全域性預設的認證方案

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework.authentication.BasicAuthentication',   # 基本認證
        'rest_framework.authentication.SessionAuthentication',  # session認證
    )
}

也可以在每個檢視中通過設定authentication_classess屬性來設定

from rest_framework.authentication import SessionAuthentication, BasicAut_framework.views import APIView

class ExampleView(APIView):
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    ...

認證失敗會有兩種可能的返回值:

  • 401 Unauthorized 未認證
  • 403 Permission Denied 許可權被禁止

####################################################

許可權Permissions

許可權控制可以限制使用者對於檢視的訪問和對於具體資料物件的訪問。

  • 在執行檢視的dispatch()方法前,會先進行檢視訪問許可權的判斷
  • 在通過get_object()獲取具體物件時,會進行物件訪問許可權的判斷

可以在配置檔案中設定預設的許可權管理類,如

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

如果未指明,則採用如下預設配置

'DEFAULT_PERMISSION_CLASSES': (
   'rest_framework.permissions.AllowAny',
)

也可以在具體的檢視中通過permission_classes屬性來設定,如

from rest_framework.permissions import IsAuthenticated
from rest_framework.views import APIView

class ExampleView(APIView):
    permission_classes = (IsAuthenticated,)
    ...

提供的許可權

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

舉例

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
class BookDetailView(RetrieveAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]

自定義許可權

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

  • .has_permission(self, request, view) 是否可以訪問檢視, view表示當前檢視物件
  • .has_object_permission(self, request, view, obj) 是否可以訪問資料物件, view表示當前檢視, obj為資料物件

例如:

class MyPermission(BasePermission):
    def has_object_permission(self, request, view, obj):
        """控制對obj物件的訪問許可權,此案例決絕所有對物件的訪問"""
        return False
class BookInfoViewSet(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    permission_classes = [IsAuthenticated, MyPermission]

##########################################################

限流Throttling

可以對介面訪問的頻次進行限制,以減輕伺服器壓力。

使用:

可以在配置檔案中,使用

DEFAULT_THROTTLE_CLASSES 和 DEFAULT_THROTTLE_RATES   進行全域性配置
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.AnonRateThrottle',
        'rest_framework.throttling.UserRateThrottle'
    ),
    'DEFAULT_THROTTLE_RATES': {
        'anon': '100/day',
        'user': '1000/day'
    }
}

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hour 或day來指明週期。

也可以在具體檢視中通過throttle_classess屬性來配置,如:

from rest_framework.throttling import UserRateThrottle
from rest_framework.views import APIView

class ExampleView(APIView):
    throttle_classes = (UserRateThrottle,)
    ...

可選限流類

  1. AnonRateThrottle 限制所有匿名未認證使用者,使用IP區分使用者。
  2. UserRateThrottle 限制認證使用者,使用User id 來區分。
  3. ScopedRateThrottle 限制使用者對於每個檢視的訪問頻次,使用ip或user id。

例如:

class ContactListView(APIView):
	throttle_classes = (ScopedRateThrottle,)
    throttle_scope = 'contacts'
    ...

class ContactDetailView(APIView):
	throttle_classes = (ScopedRateThrottle,)
    throttle_scope = 'contacts'
    ...

class UploadView(APIView):
	throttle_classes = (ScopedRateThrottle,)
    throttle_scope = 'uploads'
    ...
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': (
        'rest_framework.throttling.ScopedRateThrottle',
    ),
    'DEFAULT_THROTTLE_RATES': {
        'contacts': '1000/day',
        'uploads': '20/day'
    }
}

例項:

from rest_framework.authentication import SessionAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.generics import RetrieveAPIView
from rest_framework.throttling import UserRateThrottle

class BookDetailView(RetrieveAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    authentication_classes = [SessionAuthentication]
    permission_classes = [IsAuthenticated]
    throttle_classes = (UserRateThrottle,)

######################################################

分頁Pagination

REST framework提供了分頁的支援。

我們可以在配置檔案中設定全域性的分頁方式,如:

REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS':  'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 100  # 每頁數目
}

也可通過自定義Pagination類,來為檢視新增不同分頁行為。在檢視中通過pagination_class屬性來指明。

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 每頁數目
  • page_query_param 前端傳送的頁數關鍵字名,預設為"page"
  • page_size_query_param 前端傳送的每頁數目關鍵字名,預設為None
  • max_page_size 前端最多能設定的每頁數量
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

###################################################

過濾Filtering

對於列表資料可能需要根據欄位進行過濾,我們可以通過新增django-fitlter擴充套件來增強支援。

pip insall django-filter

在配置檔案中增加過濾後端的設定:

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

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': 	('django_filters.rest_framework.DjangoFilterBackend',)
}

在檢視中新增filter_fields屬性,指定可以過濾的欄位

class BookListView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer
    filter_fields = ('btitle', 'bread')

127.0.0.1:8000/books/?btitle=西遊記