zoukankan      html  css  js  c++  java
  • 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

    
    
  • 相关阅读:
    POJ-1189 钉子和小球(动态规划)
    POJ-1191-棋盘分割(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 730 统计不同回文子字符串(动态规划)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 729 我的日程安排表 I(二叉树)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
    Java实现 LeetCode 728 自除数(暴力)
  • 原文地址:https://www.cnblogs.com/knighterrant/p/10568961.html
Copyright © 2011-2022 走看看