Drf认证组件
eg:个别接口需要登录后才可以使用 局部使用
# 需要编写一个认证类
# 在py文件中创建一个认证类的py文件authentication.py
通过继承来编写:eg:登录验证
from rest_framework.authentication import BaseAuthentication
# 编写认证组件需要继承 认证类
from rest_framework.exceptions import AuthenticationFailed
# 认证失败报异常模块
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.META.get('HTTP_TOKEN')
# 从请求头中获取token
if token:
user_token = UserToken.objects.filter(token=token).first()
# 判断前端传的token是否正确 是否存在
if user_token:
return user_token.usertoken, token
# 存在即代表已登录,通过外键获得用户对象
else:
raise AuthenticationFailed('token认证失败')
# 认证失败要抛异常 调用模块
else:
raise AuthenticationFailed('暂未登录')
# 视图类绑定认证---------------------------------------
class BooksDetailView(GenericViewSet, RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
authentication_classes = [LoginAuth]
# 通过authentication_classes来设置执行的认证器,认证成功以后才可以使
# 用类中的方法
总结:
# 1 写一个认证类,继承BaseAuthentication
# 2 重写authenticate方法,在该方法在中实现登录认证:token正确即为登录
# 3 如果认证成功,返回两个值【返回用户对象,和 token】
# 4 认证不通过,抛异常AuthenticationFailed
# 5 局部使用和全局使用
全局使用/局部不使用
# 在settings.py文件中最下方添加该认证类,这样默认就是给所有的接口都生效
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES'['app01.authenticate.LoginAuth']
}
# 如何要局部不使用:
class BooksDetailView(GenericViewSet, RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
authentication_classes = []
# 只需要在局部把这个认证类置空即可,那么这个类里面的接口都不需要认证了
Drf权限组件
eg:某些接口需要管理员身份,或vip等才可以使用
局部配置
# 需要编写一个权限类
# 在py文件中创建一个认证类的py文件permissions.py
from rest_framework.permissions import BasePermission
# 导入权限设置类
class CommonPermission(BasePermission):
# 继承类并重新方法
def has_permission(self, request, view):
if request.user.user_type == 1:
# 判断用户权限是否符合
return True
# 权限符合通过就返回 True
else:
self.message = f'您是{request.user.get_user_type_display()}'
# 返回错误信息,错误信息在self.message中
return False
# 权限不对就返回 false
知识点:{request.user.get_user_type_display()}
# 搭配数据库中choices=((1,'超级管理员'),(2,'普通用户'))使用
# 通过get_字段名__display()方法可以把数字对应的说明取出来
# 视图类----------------------------------------
class BooksDetailView(GenericViewSet, RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = [CommonPermission]
# 设置该接口需要的权限类即可
# 局部配置
全局配置
# 在settings.py文件中最下方添加该认证类,这样默认就是给所有的接口都生效
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentications.LoginAuth'],
'DEFAULT_PERMISSION_CLASSES': ['app01.permissions.CommonPermission']
}
# 全局配置
# 局部禁止
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
authentication_classes = []
permission_classes = []
# 局部取消权限认证
总结:
# 1 写一个权限类,继承BasePermission
# 2 重写has_permission方法,在该方法在中实现权限认证,在这方法中,request.user就是当前登录用户
# 3 如果有权限,返回True
# 4 没有权限,返回False, 要定制返回的中文: self.message='中文'
# 5 局部使用和全局使用
Drf频率组件
# 需要编写一个频率类
# 在py文件中创建一个认证类的py文件throttling.py
from rest_framework.throttling import SimpleRateThrottle
# 导入需要继承的类
class Throttling(SimpleRateThrottle):
scope = 'booksListThrottling'
# 设置这个类的别名
def get_cache_key(self, request, view):
return request.META.get('REMOTE_ADDR')
# 这里返回什么就什么做限制,现在是已ip地址做限制
# return request.user.pk 这种是按照用户id限制
视图类---------------------------------------
class BooksDetailView(GenericViewSet, RetrieveAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
throttle_classes = [Throttling]
# 导过来刚刚写的频率类即可生效
设置频率类的参数------------------------------
django的sttings文件中配置
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentications.LoginAuth'],
'DEFAULT_PERMISSION_CLASSES': ['app01.permissions.CommonPermission'],
'DEFAULT_THROTTLE_RATES': {
'booksListThrottling': '5/m',
# 配置别名为booksListThrottling的频率类,频率为1分钟5次访问
},
}
# 1 写一个频率类,继承SimpleRateThrottle
# 2 重写get_cache_key方法,返回什么,就以什么做限制----》ip,用户id做限制
# 3 配置一个类属性:scope = 'book_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 = []
drf三种过滤方式
restful规范中要求,请求地址中带过滤条件
eg:
只有一个接口需要过滤和排序,就是:查所有接口
# 方式一: 内置模块 模糊搜索
from rest_framework.filters import SearchFilter
# 内置的过滤功能,模糊匹配
# 必须搭配GenericAPIView或其子类使用
lass BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
# 权限设置功能置空
throttle_classes = [Throttling]
# 频率设置功能
filter_backends = [SearchFilter]
# 固定语法用法
search_fields = ['name']
# 配置要模糊搜索的表字段名
http://127.0.0.1:8003/api/books/?search=海
# 必要要用search来使用
# 这样就实现了模糊搜索 名字中带有海的图书名
精确查找 第三方查询模块Django-filter
from django_filters.rest_framework import DjangoFilterBackend
# 需要导入这个类
# 视图类中代码
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
throttle_classes = [Throttling]
filter_backends = [DjangoFilterBackend]
# 固定配置用法 带入DjangoFilterBackend类
filterset_fields = ['name']
# 设置精确查找字段 也可以设置多个 and关系
http://127.0.0.1:8003/api/books/?name=海贼王
# 不需要搭配search来使用了
# 只能精确查找,找不到返回空
自定义搜索类
# 需要编写一个频率类
# 在py文件中创建一个认证类的py文件filter.py 存放编写的自定义过滤类
from rest_framework.filters import BaseFilterBackend
# 继承该类 进行编写
class booksfilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
# 在里面实现过滤,返回queryset对象就是过滤后的对象
# eg:价格大于100的图书,
price_gt = request.query_params.get('price_gt', None)
# 从get请求头里面拿到要搜索的条件
if price_gt:
return queryset.filter(price__gt=int(price_gt))
# 字段实现__gt大于方法 需要该字段为整形才可以
# 将符合条件的对象返回出去
else:
return queryset
视图类---------------------------
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
throttle_classes = [Throttling]
filter_backends = [SearchFilter,DjangoFilterBackend,booksfilter]
# 可以同时支持多个过滤类方法,从左到右生效
search_fields = ['name','price']
# 固定配置用法
filterset_fields = ['name','price']
# 对表字段name进行搜索,只支持精确搜索
# http://127.0.0.1:8003/api/books/?search=海 触发SearchFilter模糊搜索
# http://127.0.0.1:8003/api/books/?name=海贼王 DjangoFilterBackend的精确搜索
# http://127.0.0.1:8003/api/books/?price_gt=100
# 触发自己定制的搜索类,自己定制的方法price_gt 查找单价大于100的
排序的使用
使用drf内置模块即可
# 视图类----------
from rest_framework.filters import OrderingFilter
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
throttle_classes = [Throttling]
filter_backends = [OrderingFilter,SearchFilter,DjangoFilterBackend,booksfilter]
# 排序的类放到最前面
search_fields = ['name','price']
# 固定配置用法
filterset_fields = ['name','price']
ordering_fields = ['price']
# 设置需要排序的字段
http://127.0.0.1:8003/api/books/?ordering=price
# 触发排序的方法 对price字段进行排序 默认升序 从小到大
# ordering=-price 从大到小 加上-号
分页
只有查询所有接口才有分页
def内置3个分页器
分页器一(最常用,网页端)
# 必须继承 GenericAPIView 或子类 才可以使用
# # 需要编写一个分页类
# 在py文件中创建一个认证类的py文件Page.py
from rest_framework.pagination import PageNumberPagination
class booksPageNumber(PageNumberPagination):
page_size = 2
# 控制每页显示条数,每页显示2条
page_query_param = 'page'
# 查询第10页的数据,一般不需要改
page_size_query_param = 'size'
# page=10&size=5 查询第10页 每页显示2条
max_page_size = 10
# 每页最大显示条数设置
视图类-------------直接配置上就可以了
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
authentication_classes = []
throttle_classes = []
filter_backends = [OrderingFilter,SearchFilter,DjangoFilterBackend,booksfilter]
search_fields = ['name','price']
# 固定配置用法
filterset_fields = ['name','price']
ordering_fields = ['price']
pagination_class = booksPageNumber
# 这里配置上写好的booksPageNumber分页类就可以实现了
http://127.0.0.1:8003/api/books/
# 不写默认是第一页
http://127.0.0.1:8003/api/books/?page=2%size=10
# 查询第二页 显示10条,但是这个最大显示数还是根据分页类中设置的
分页器二(偏移取值)不常用
# 在py文件中创建一个认证类的py文件Page.py
from rest_framework.pagination import PageNumberPagination, \
LimitOffsetPagination, CursorPagination
class booksLimitOffsetPagination(LimitOffsetPagination):
default_limit = 2
# 控制每页显示条数,每页显示2条
limit_query_param = 'limit'
# 查询页数控制关键字 limit=2 查询第二页
offset_query_param = 'offset'
# offset=1 位置偏移设置,从第一个位置取 索引取值
max_limit = 10
# 最大显示数
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
authentication_classes = []
pagination_class = booksLimitOffsetPagination
# 配置分页器
http://127.0.0.1:8003/api/books/?limit=4&offset=1
# 意思是 位置偏移1 从一个位置以后拿4个数据 12345拿2345
分页器三 游标分页 app项目经常使用
# 在py文件中创建一个认证类的py文件Page.py
from rest_framework.pagination import CursorPagination
class BooksCursorPagination(CursorPagination):
cursor_query_param = 'cursor'
# "http://127.0.0.1:8003/api/books/?cursor=cD01",
# 设置显示的关键词
page_size = 2
# 设置每页显示条数
ordering = 'id'
#游标分页自带排序,设置根据排序的字段
class BooksView(GenericViewSet, ListAPIView, CreateAPIView, ):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
authentication_classes = []
throttle_classes = []
filter_backends = [SearchFilter,DjangoFilterBackend,booksfilter]
search_fields = ['name','price']
# 固定配置用法
filterset_fields = ['name','price']
ordering_fields = ['price']
pagination_class = BooksCursorPagination
# 匹配游标分页类 使用游标分类后就不可以使用drf的排序了,因为游标分页自带排序
# 游标分页只能下一页或者上一页,不能直接取中间的,类似app下滑上滑
# 但游标分页效率最高 大数据量推荐使用
标签:price,py,queryset,认证,classes,组件,排序,class,drf
From: https://www.cnblogs.com/moongodnnn/p/17100001.html