首页 > 其他分享 >认证组件、权限组件、频率组件、过滤排序、分页

认证组件、权限组件、频率组件、过滤排序、分页

时间:2023-02-07 21:13:59浏览次数:50  
标签:排序 ViewSetMixin 认证 token classes 组件 import 权限 class

认证组件、权限组件、频率组件、过滤排序、分页

认证组件

1.认证组件

### 视图
from rest_framework.generics import ListAPIView,RetrieveAPIView
from rest_framework.mixins import RetrieveModelMixin
from rest_framework.viewsets import ViewSetMixin
from .authenticate import LoginAuth
# 查询所有
class BookView(ViewSetMixin,ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer


#查询单个
class BookDetailView(ViewSetMixin,RetrieveAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    authentication_classes = [LoginAuth]
### 认证类代码
# 自己写一个认证类,继承某个类
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
from .models import UserToken
class LoginAuth(BaseAuthentication):
    def authenticate(self, request):
    # 在这里实现认证,如果是登录的,继续往后走返回两个值,如果不是抛异常
    # 请求中是否携带token,判断是否登录,放在地址栏中
        token = request.query_params.get('token',None)
        if token:
            # 前端传入token了,去表中查,如果能查到,登录了,返回两个值[固定的:当前登录用户,token]
            user_token = UserToken.objects.filter(token=token).first()
            if user_token:
                return user_token.user,token
            else:
                # 没有登录就抛异常
                raise AuthenticationFailed('token认证失败')
        else:
            raise AuthenticationFailed('token没有传')
  1. 认证组件使用步骤

有的接口需要登录后才能访问,有的接口,不登录就能访问 ------>登录认证的限制
写一个登录接口,返回token,以后只要带着token过来,就是登录了,不带,就没有登录
# 查询所有不需要登录就能访问
# 查询单个,需要登录才能访问
 1 写一个认证类,继承BaseAuthentication
 2 重写authenticate方法,在该方法在中实现登录认证:token在哪带的?如果认证它是登录了
 3 如果认证成功,返回两个值【返回None或两个值】
 4 认证不通过,抛异常AuthenticationFailed
 5 局部使用和全局使用
	局部:只在某个视图类中使用【当前视图类管理的所有接口】
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
            authentication_classes = [LoginAuth] 
    全局:全局所有接口都生效(登录接口不要)
    REST_FRAMEWORK = {
    	'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth']
	}
    
    局部禁用:
    	 class BookDetailView(ViewSetMixin, RetrieveAPIView):
            authentication_classes = [] 

权限组件

1 权限的使用

 1 写一个权限类,继承BasePermission
 2 重写has_permission方法,在该方法在中实现权限认证,在这方法中,request.user就是当前登录用户
 3 如果有权限,返回True
 4 没有权限,返回False,定制返回的中文: self.message='中文'
 5 局部使用和全局使用
	局部:只在某个视图类中使用【当前视图类管理的所有接口】
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
    		permission_classes = [CommonPermission]
    全局:全局所有接口都生效
          REST_FRAMEWORK = {
            'DEFAULT_PERMISSION_CLASSES': [
                'app01.permissions.CommonPermission',
            ],

        }
    
    -局部禁用:
    	 class BookDetailView(ViewSetMixin, RetrieveAPIView):
            permission_classes = [] 

2.代码

###### 权限类代码
写权限类,写一个类,继承基类BasePermission,重写has_permission方法,在方法中实现权限认证,如果有权限return True ,如果没有权限,返回False
from rest_framework.permissions import BasePermission
class CommonPermission(BasePermission):
    def has_permission(self, request, view):
        # 实现权限的控制
        if request.user_type ==1:
            return True
        else:
            # 没有权限,向对象放一个属性
            # 如果表模型中,使用了choice,就可以通过  get_字段名_display()  拿到choice对应的中文
            self.message = '您是[%s],您没有权限' % request.user.get_user_type_display()
            return False

频率组件

1.使用步骤

 1 写一个频率类,继承SimpleRateThrottle
 2 重写get_cache_key方法,返回什么,就以什么做限制----》ip,用户id做限制
 3 配置一个类属性:scope = 'rate_5_m'
 4 在配置文件中配置
  'DEFAULT_THROTTLE_RATES': {
        'book_5_m': '5/m',
    },
5 局部使用和全局使用
	-局部:只在某个视图类中使用【当前视图类管理的所有接口】
        class BookDetailView(ViewSetMixin, RetrieveAPIView):
    		throttle_classes = [CommonThrottle]
    -全局:全局所有接口都生效
          REST_FRAMEWORK = {
             'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.CommonThrottle'],

        }
    
    -局部禁用:
    	 class BookDetailView(ViewSetMixin, RetrieveAPIView):
            throttle_classes = [] 

2.代码

### 视图
from .permissions import CommonPermission
from .throttling import CommonThrottle
#查询单个
class BookDetailView(ViewSetMixin,RetrieveAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    # authentication_classes = [LoginAuth]
    authentication_classes = [CommonThrottle]
### 认证类代码
# 频率类,继承SimpleRateThrottle
from rest_framework.throttling import SimpleRateThrottle
class CommonThrottle(SimpleRateThrottle):
    # 类属性,属性值随便写,在配置文件中配置
    scope = 'rate_5_m'
    def get_cache_key(self, request, view):
        # return request.META.get('REMOTE_ADDR')    #ip做限制
        return request.user.pk                      # id做限制
### 配置代码
REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_RATES': {
        'rate_5_m':'5/m'
    },
    'DEFAULT_THROTTLE_CLASSES':['app01.throttling.CommonThrottle'],


}

过滤排序

1 内置过滤类的使用【继承GenericAPIView】

class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    #  SearchFilter内置的,固定用法,模糊匹配
    #  就有过滤功能了,指定按哪个字段过滤
    filter_backends = [SearchFilter]
    # search_fields = ['name']  # 可以按名字模糊匹配
    search_fields = ['name','price']  # 可以按名字模糊匹配或价格模糊匹配
    
# 可以使用的搜索方式
	http://127.0.0.1:8000/api/v1/books/?search=人  # name或price中只要有人就会搜出来

image

2 使用第三方djagno-filter实现过滤


# 第三方过滤类
from django_filters.rest_framework import DjangoFilterBackend
class BookView(ViewSetMixin,ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    permission_classes = []
    authentication_classes = []
    throttle_classes = []
    # SearchFilter内置的固定用法,模糊匹配
    filter_backends = [DjangoFilterBackend]
    filter_backends = ['name']
# 支持的查询方式
http://127.0.0.1:8000/api/v1/books/?price=939
http://127.0.0.1:8000/api/v1/books/?price=939&name=在人间等白头

image

image

image

3 自己定制过滤类实现过滤

# 自定义过滤类
from django_filters.rest_framework import DjangoFilterBackend
from .filter import CommonFilter
from rest_framework.filters import OrderingFilter

class BookView(ViewSetMixin,ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    permission_classes = []
    authentication_classes = []
    throttle_classes = []
    # SearchFilter内置的固定用法,模糊匹配
    filter_backends = [OrderingFilter,CommonFilter]
    ordering_fields = ['name']
from rest_framework.filters import BaseFilterBackend
class CommonFilter(BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        price_gt = request.query_params.get('price_gt',None)
        if price_gt:
            qs = queryset.filter(price__gt = int(price_gt))
            return qs
        else:
            return queryset

4 排序的使用

# 内置的就够了
class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [OrderingFilter]  
    ordering_fields = ['price']

分页

class BookView(ViewSetMixin, ListAPIView):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    permission_classes = []
    authentication_classes = []
    throttle_classes = []

    pagination_class = CommonCursorPagination
    # 游标分页,只能下一页,上一页,不能跳到中间,但它的效率最高,大数据量分页,使用这种较好
from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination


# 网页用它
class CommonPageNumberPagination(PageNumberPagination):
    page_size = 2  # 每页显示2条
    page_query_param = 'page'  # page=10  查询第10页的数据,每页显示2条
    page_size_query_param = 'size'  # page=10&size=5    查询第10页,每页显示5条
    max_page_size = 5  # 每页最大显示10条


# LimitOffset
class CommonLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 3  # 每页显示2条
    limit_query_param = 'limit'  # limit=3   取3条
    offset_query_param = 'offset'  # offset=1  从第一个位置开始,取limit条
    max_limit = 5
    # offset=3&limit=2      0  1 2 3 4 5


# app 用这个

class CommonCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'  # 查询参数
    page_size = 2  # 每页多少条
    ordering = 'id'  # 排序字段

标签:排序,ViewSetMixin,认证,token,classes,组件,import,权限,class
From: https://www.cnblogs.com/zx0524/p/17099805.html

相关文章