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相关的知识点。如若文中出现问题,各位大佬多多指点,互相学习。喜欢的关注一个吧!谢谢!


    分享到:


    相關文章: