DRF:认证、权限、频率、分页

Token认证

1、用户表设置token字段
2、写认证类MyAuth
    -继承BaseAuthentication
    -实现authenticate方法
        写认证逻辑,返回user对象和token值
        抛异常AuthenticationFailed,from rest_framework.exceptions import AuthenticationFailed
        
3、应用token认证
    -单视图:authentication_classes = [MyAuth]
            authentication_classes = []  # 设置了全局认证,而某些视图不需要认证时
    -全局使用:settings
        REST_FRAMEWORK = {
            "DEFAULT_AUTHENTICATION_CLASSES": ["***.MyAuth", ]
        }
token放在url上传给后端 ?_token=asdasdas
    request.auth = request._request.GET.get("_token") = request.GET.get("_token")
from rest_framework.exceptions import AuthenticationFailed
from authDemo.models import User
from rest_framework.authentication import BaseAuthentication


class MyAuth(BaseAuthentication):

    def authenticate(self, request):
        # 做认证 看他是否登录
        # 从url过滤条件里拿到token
        # 去数据库看token是否合法
        # 合法的token能够获取用户信息
        token = request.query_params.get("token", "")
        if not token:
            raise AuthenticationFailed("没有携带token")
        user_obj = User.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed("token不合法")
        # return (None, None)
        return (user_obj, token)
MyAuth
class TestView(APIView):
    authentication_classes = [MyAuth,]
    permission_classes = [MyPermission, ]
    throttle_classes = [MyThrottle, ]

    def get(self, request):
        print(request.user)
        print(request.auth)
        user_id = request.user.id
        return Response("认证测试")
Views

 

权限

1、用户表设置权限识别字段,枚举类型
2、写权限类:request, view两个参数
    message: 认证失败返回的信息
    has_permission:无权限return False
    3、应用权限
    视图中
    permission_classes = [MyPermission, ]
    from rest_framework.permissions import BasePermission
    class MyPermission(BasePermission):
        message = "您没有权限"

        def has_permission(self, request, view):
            # 判断用户是否有权限
            user_obj = request.user
            if user_obj.type == 3:
                return False
            else:
                return True   
MyPermission

 

频率:

频率限制单视图设置,不建议设置全站统一

1、写频率限制类
  继承SimpleRateThrottle, 定义scope属性,实现get_cache_key方法
    from rest_framework.throttling import SimpleRateThrottle

    class MyThrottle(SimpleRateThrottle):
        scope = "MyThrottle"

        def get_cache_key(self, request, view):
            # get_ident:以IP限制访问次数
            # 如果以其他为限制依据,自定义方法
            key = self.get_ident(request)
            return key        

2、配置文件
    REST_FRAMEWORK = {
        "DEFAULT_THROTTLE_RATES": {"MyThrottle": "3/m"}
                            类中定义的scope的值: 次数/时间
    }
        s:1秒
        m:60秒
        h:1小时 3600秒
        d:1天 3600*24秒

3、应用
    视图中
    throttle_classes = [MyThrottle, ]

 

分页

不需要在settings做设置

from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination

********1********
class MyPagination(PageNumberPagination):
    # xxxx?page=1&size=2
    # 如果路由上配置了size参数,则使用路由,否则使用默认page_size
    page_size = 1
    page_query_param = "page"
    page_size_query_param = "size"
    max_page_size = 3

********2********
class MyPagination(LimitOffsetPagination):
    # 路由必须传offset,limit可选,
    # 从第几条(offset)开始找几条(limit)
    default_limit = 1
    limit_query_param = "limit"
    offset_query_param = "offset"
    max_limit = 3

********3********
class MyPagination(CursorPagination):
    # 路由不需要传参数,且对分页信息加密
    cursor_query_param = "cursor"
    page_size = 2   # 每页显示数据量
    ordering = "-id"  # 排序方式
定义分页类(三种)
视图继承APIView
    class BookView(APIView):

        def get(self, request):
            queryset = Book.objects.all()
            # 1,实例化分页器对象
            page_obj = MyPagination()
            # 2,调用分页方法去分页queryset
            page_queryset = page_obj.paginate_queryset(queryset, request, view=self)
            # 3,把分页好的数据序列化返回
            # 4, 带着上一页下一页连接的响应
            ser_obj = BookSerializer(page_queryset, many=True)

            return page_obj.get_paginated_response(ser_obj.data)

视图继承GenericAPIView, ListModelMixin
    class BookView(GenericAPIView, ListModelMixin):
        queryset = Book.objects.all()
        serializer_class = BookSerializer
        pagination_class = MyPagination  # *****
        # self.paginate_queryset(queryset)

        def get(self, request):
            return self.list(request)
使用

 

posted @ 2018-11-16 10:20  web123  阅读(106)  评论(0编辑  收藏  举报