认证组件、权限组件、频率组件、过滤排序、分页
认证组件
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没有传')
-
认证组件使用步骤
有的接口需要登录后才能访问,有的接口,不登录就能访问 ------>登录认证的限制
写一个登录接口,返回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中只要有人就会搜出来
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=在人间等白头
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