drf 认证、权限、限流、过滤、排序、分页器

认证Authentication

准备工作:(需要结合权限用)

1. 需要使用到登陆功能,所以我们使用django内置admin站点并创建一个管理员。

python manage.py createsuperuser

2. 配置  settings.py

  1.站点语言配置

# LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'zh-hans'  # 配置中文

开始认证Authentication 配置文件:

(1)可以在配置文件中配置全局默认的认证方案

REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (  # 默认响应渲染类
        'rest_framework.renderers.JSONRenderer',  # json渲染器
        'rest_framework.renderers.BrowsableAPIRenderer',  # 浏览API渲染器
    ),

    # 认证数据的记录方式
    'DEFAULT_AUTHENTICATION_CLASSES': (
        # 这里我们会加上jwt
        'rest_framework.authentication.BasicAuthentication',  # 基本认证
        'rest_framework.authentication.SessionAuthentication',  # session认证
    ),}

(2)也可以在每个视图中通过设置authentication_classess属性来设置

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

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

认证失败会有两种可能的返回值:

  • 401 Unauthorized 未认证

  • 403 Permission Denied 权限被禁止

2. 权限Permissions

权限控制可以限制用户对于视图的访问和对于具体数据对象的访问。

  • 在执行视图的dispatch()方法前,会先进行视图访问权限的判断

  • 在通过get_object()获取具体对象时,会进行模型对象访问权限的判断

使用

1.可以在配置文件中设置默认的权限管理类,如

# 权限管理类
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}

如果未指明,则采用如下默认配置,在REST_FRAMEWORK ={}中:

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

2.也可以在具体的视图中通过permission_classes属性来设置,views.py 中:from rest_framework.decorators import action

from rest_framework.viewsets import ModelViewSet
from book.models import Book
from .serializers import BookModelSerializer

# 用户认证
from rest_framework.authentication import BaseAuthentication,SessionAuthentication
# 权限
from rest_framework.permissions import IsAuthenticated

from rest_framework.permissions import BasePermission
# 自定义权限 ,必须继承 BasePermission
class CustomPermission(BasePermission):
    def has_permission(self, request, view):
        # 当前权限方法用于判断访问者是否有权限访问对应的视图
        # 获取当前已经登录的用户可以用request.user
        return request.user.username=='wang' # 返回的是布尔值

# 视图: class BookModelSetView(ModelViewSet): queryset = Book.objects.all() serializer_class = BookModelSerializer # 只是设置了认证方式,还需要结合权限来 ,这里会报错, .authenticate() must be overridden. #authentication_classes = [SessionAuthentication,BaseAuthentication] # 权限 # permission_classes = [IsAuthenticated] permission_classes = [CustomPermission]

提供的权限

  • AllowAny 允许所有用户

  • IsAuthenticated 仅通过认证的用户

  • IsAdminUser 仅管理员用户

  • IsAuthenticatedOrReadOnly 已经登陆认证的用户可以对数据进行增删改操作,没有登陆认证的只能查看数据。

自定义权限

如需自定义权限,需继承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]
 

3. 限流Throttling

可以对接口访问的频次进行限制,以减轻服务器压力。

使用

1. 可以在配置文件中,使用DEFAULT_THROTTLE_CLASSESDEFAULT_THROTTLE_RATES进行全局配置,

REST_FRAMEWORK = {
# 限流
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',# 普通用户
'rest_framework.throttling.UserRateThrottle' # 登录用户
),
'DEFAULT_THROTTLE_RATES': {
'anon': '3/day', # 一天只能访问3次
'user': '5/day' # 一天只能访问5次
},
 }

DEFAULT_THROTTLE_RATES 可以使用 second, minute, hourday来指明周期。

2.也可以在具体视图中通过throttle_classess属性来配置,如

from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from book.models import Book
from .serializers import BookModelSerializer

# 限流
from rest_framework.throttling import AnonRateThrottle,UserRateThrottle
class BookModelSetView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
    # 限流
    throttle_classes = [AnonRateThrottle,UserRateThrottle]

 

可选限流类

1) AnonRateThrottle

限制所有匿名未认证用户,使用IP区分用户。

使用DEFAULT_THROTTLE_RATES['anon'] 来设置频次

2)UserRateThrottle

限制认证用户,使用User id 来区分。

使用DEFAULT_THROTTLE_RATES['user'] 来设置频次

3)ScopedRateThrottle

限制用户对于每个视图的访问频次,使用ip或user id。

例如:

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

4. 过滤Filtering

对于列表数据可能需要根据字段进行过滤,我们可以通过添加django-fitlter扩展来增强支持。

pip install django-filter

1.在配置文件中增加过滤后端的设置:

  1.注册应用:

INSTALLED_APPS = [
 
    'django_filters',  # 需要注册应用,
]

  2.配置

# drf框架的配置字典,所以关于drf的配置信息,要记录在这里即可。
REST_FRAMEWORK = {
    
'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',),

}

在视图中添加filter_fields属性,指定可以过滤的字段

访问时:127.0.0.1:8000/books/?btitle=西游记
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from book.models import Book
from .serializers import BookModelSerializer
#  过滤排序
from rest_framework.filters import OrderingFilter

class BookModelSetView(ModelViewSet):

    queryset = Book.objects.all()

    serializer_class = BookModelSerializer
    # 过滤
    filter_fields = ('title', 'bread')
 

5. 排序

对于列表数据,REST framework提供了OrderingFilter过滤器来帮助我们快速指明数据按照指定字段进行排序。

使用方法:

在类视图中设置filter_backends,使用rest_framework.filters.OrderingFilter过滤器

REST framework会在请求的查询字符串参数中检查是否包含了ordering参数,如果包含了ordering参数,

则按照ordering参数指明的排序字段对数据集进行排序。

前端可以传递的ordering参数的可选字段值需要在ordering_fields中指明。

示例:

# 127.0.0.1:8000/books/?ordering=-bread
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from book.models import Book
from .serializers import BookModelSerializer

#  过滤排序
from rest_framework.filters import OrderingFilter

class BookModelSetView(ModelViewSet):

    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
       # 过滤
    filter_fields = ('title', 'bread')
    # 过滤排序
    filter_backends = [OrderingFilter]
    OrderingFilter=['id','bread','bcommnet']

6. 分页Pagination

REST framework提供了分页的支持。

1.可以在配置文件中设置全局的分页方式,如:

# drf框架的配置字典,所以关于drf的配置信息,要记录在这里即可。
REST_FRAMEWORK = {
   # 分页配置[全局配置,针对整个项目所有列表视图都会产生分页效果]
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 2,  # 每页数目
}

2.也可通过自定义Pagination类,来为视图添加不同分页行为。在视图中通过pagination_clas属性来指明。

from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
from book.models import Book
from .serializers import BookModelSerializer
# 自定义分页器
from rest_framework.pagination import PageNumberPagination
class BookPageNumberPagination(PageNumberPagination):
    page_size = 3
    max_page_size = 10
    page_query_param = 'page_size'
    ## http;//loclahost/?page_size=5

class BookModelSetView(ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookModelSerializer
  # 分页
    # 指定当前视图类的列表视图[局部配置]
    # pagination_class = BookPageNumberPagination
    pagination_class = None  # 阻止全局的分页配置给当前的列表视图生成分页效果

注意:如果在视图内关闭分页功能,只需在视图内设置

pagination_class = None

可选分页器

1) PageNumberPagination

前端访问网址形式:

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

可以在子类中定义的属性:

  • page_size 每页数目

  • page_query_param 前端发送的页数关键字名,默认为"page"

  • page_size_query_param 前端发送的每页数目关键字名,默认为None

  • max_page_size 前端最多能设置的每页数量

view.py 视图中:

from rest_framework.pagination import PageNumberPagination
​
class StandardPageNumberPagination(PageNumberPagination):
    page_size_query_param = 'page_size'
    max_page_size = 10class 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

2)LimitOffsetPagination

前端访问网址形式:

GET http://api.example.org/books/?limit=100&offset=400

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一直

  • limit_query_param limit参数名,默认'limit'

  • offset_query_param offset参数名,默认'offset'

  • max_limit 最大limit限制,默认None

猜你喜欢

转载自www.cnblogs.com/knighterrant/p/10568961.html
今日推荐