drf day07 drf三大认证、过滤、排序、分页
一、认证组件
1.作用
以后有的接口,需要登录后才能访问,类似bbs项目,django auth模块的认证
2.如何使用
1.自己建立一个Py文件,导入一下认证模块
from rest_framework.authentication import BaseAuthentication
2.自己写一个认证类,继承BaseAuthentication
3.在类中重写authenticate方法,返回两个值或者None,第一个值是当前登录用户,这个值会被给request.user(反正就是被给了)
请求中是否携带token来判断是否登录,因为我们用的这个认证组件可能会面临很多中请求方式,什么GET啊,POST,DELETE之类的,GET请求体中不能携带数据,所以只能把token塞在请求地址中,不过后面实际项目是放在请求头
request.META 所有请求头数据
4.视图类中,导入自己写的py文件,添加一个属性,authentication_class = [自己写的Py文件名],即可完成认证
代码实现:
# 视图层
class BooksView(ViewSetMixin, ListAPIView):
queryset = Book.objects
serializer_class = BookSerializers
from .authentication import LoginAuth
class BooksDetailView(ViewSetMixin, RetrieveAPIView):
queryset = Book.objects
serializer_class = BookSerializers
authentication_classes = [LoginAuth]
# 自己写的认证py文件
from rest_framework.authentication import BaseAuthentication
from .models import User, UserToken
from rest_framework.exceptions import AuthenticationFailed
class LoginAuth(BaseAuthentication):
def authenticate(self, request):
token = request.GET.get('token')
if token:
user_token_obj = UserToken.objects.filter(token=token).first()
if user_token_obj:
return user_token_obj.user, token
else:
raise AuthenticationFailed('认证失败')
else:
raise AuthenticationFailed('必须传token')
3.局部使用和全局使用
局部:
authentication_class = [自己写的Py文件名]
但是这样局部使用后,该类的所有接口都要经过认证组件
全局:
去django项目的配置文件配置,类似以前配置过的那个,用字符串的方式导入自己写的类,别真的导入啊!字符串的形式!
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES':['app01.authenticate.LoginAuth']
}
# 字符串的形式!app01.authenticate.LoginAuth
4.局部禁用
给要禁用认证组件的类加上:
authentication_class = [] ——等于空
二、权限组件
权限权限,校验完了登录还不够,有的网址,根据用户的权限来赋予某些功能,权限不够就没法进入接口功能
1.如何使用
1.一样,建立一个Py文件,名字随意,建议permissions.py
2.导入一下drf提供的permissions里面的BasePermission,然后写一个类来继承这个,类的名字随意
3.重写has_permission方法,这就是权限认证的核心,能过权限认证,就返回True,如果不能通过权限认证,返回False
4.然后去视图层,导一下自己写的校验文件,在要添加校验组件的类中,添加permission_classes = [xxx]
2.局部使用和全局使用
局部:
permission_classes= [自己写的Py文件名]
但是这样局部使用后,该类的所有接口都要经过认证组件
全局:
去django项目的配置文件配置,类似以前配置过的那个
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'app01.permissions.CommonPermission',
],
}
3.局部禁用
permission_classes= [] ————等于空的意思
三、频率组件
1.作用
虽然我们手机点,很少达到网站设置的访问频率值,但是爬虫之类的工具爬起来是飞快的,会在短时间内疯狂请求接口,给服务器造成巨大压力,甚至干趴服务器,所以一般开发者都会控制某个接口的访问频率,有好几种,有根据请求IP地址的的,有根据手机识别码的....
2.如何使用
1.还是一样,要自己建一个py文件,名字随意,建议throttling
2.还是一样,继承drf中的某些类
from rest_framework.throttling import BaseThrottle,SimpleRateThrottle
3.写一个类,继承SimpleRateThrottle,类名随意
4.重写get_cache_key方法,这个方法返回的是啥,频率就是以什么做限制,比如返回IP,那就是IP做限制,如果是用户ID,那就是ID做限制
5.重写完方法后,还需要给类添加一个类属性,属性的值随便写,不是给方法塞哦!!!
scope = 'xixi' # 值随便写,自己待会配置时这值就是K
6.还需要去django配置文件配置,依旧是那个REST_FRAMEWORK 大列表中添加,添加的K就是刚才写的属性的值,V就是字符串形式的控制频率的方法,比如说10/h 就是一小时十次,5/m就是 一分钟五次
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': ['app01.authentication.LoginAuth'], #上面这个不是频率的,是校验的
'DEFAULT_THROTTLE_RATES': {
'xixi': '3/m
},
}
3局部使用和全局使用
局部使用
还是一样的,类中配置
throttle_classes = [MyThrottling]
全局使用
'DEFAULT_THROTTLE_CLASSES': ['app01.throttling.MyThrottling']
4.局部禁用
一样的,要禁用的类写空属性
throttle_classes = []
四、过滤
一般只用给查全部做筛选,使用过滤的类,必须是继承GenericAPIView及其子类的才能这样用哦
注意
过滤类可以配置多个,从左至右依次执行
1.自带的过滤(SearchFilter)
1.视图类导一下drf提供的类
from rest_framework.filters import SearchFilter,OrderingFilter
2.配置一条属性,值就是我们导入的两个类的其中一个,这样就有了过滤功能
filter_backends = [SearchFilter]
3.但是还要指定过滤字段,点进去SearchFilter源码看到反射了search_fields,中文意思是搜索字段,所以我们就写这个
search_fields = ['name'] # 可以写多个,是or的关系!
4.这样就算全配好了,自带的过滤(SearchFilter)是模糊匹配,而且是前后都模糊匹配
5.POSTMAN试一试
http://127.0.0.1:8000/api/v1/books/?search= # search必须写对!然后后面写要模糊匹配的文字
2.使用第三方模块来实现
这个模块能实现筛选的字段值必须等于前端网址传的值,emmm也不是很好用
1.下载,安装第三方模块django-filter
pip install django-filter -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/
#安装第三方模块会带着给django升级到4.x,我们需要给django又降级回去
pip install django==2.2.22 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/
#版本号按你以前用习惯了版本号即可
切记执行这两个命令期间启动项目!不然项目要奔溃!
2.视图层的类中导一下
from django_filters.rest_framework import DjangoFilterBackend
3.删选属性相匹配,指定筛选字段,此时达成完全匹配
filter_backends = [DjangoFilterBackend]
filterset_fields = ['name']
4.POSTMAN试一试
http://127.0.0.1:8000/api/v1/books/?name=《老JOJO》 # 这里不是seach了是自己写的筛选字段
3.自己写的过滤
1.自己创一个过滤的Py文件,导一下drf的基础的过滤
from rest_framework.filters import BaseFilterBackend
2.重写filter_queryset方法
class MyFilter(BaseFilterBackend):
def filter_queryset(self, request, queryset, view):
price_lt = request.GET.get('price_lt') # 这里的筛选条件自己写,我这里写的是价格小于
if price_lt:
return queryset.filter(price__lt=price_lt) #这里是ORM的神奇双下划线筛选,就是比较运算
# price_lt只是个数字,别看花眼了
else:
return queryset
#注意,这里我按价格筛选的,模型层BOOK表的价格字段必须是小数,或者整形字段,如果是CharField字段,查询时要int包一下
3.然后就可以在视图层的类中使用自己写的了
from .myfilter import MyFilter
class BooksView(ViewSetMixin, ListAPIView):
queryset = Book.objects
serializer_class = BookSerializers
authentication_classes = []
permission_classes = []
throttle_classes = []
filter_backends = [MyFilter]
- POSTMAN玩一下
http://127.0.0.1:8000/api/v1/books/?price_lt=400
自带的 模糊匹配,可以多个字段匹配。是或的关系——OR
第三方 完整匹配,可以多个字段匹配。是和的关系——AND ,必须多个字段都完全匹配
五、排序
很简单
1.使用方法
# 内置的就够了
from rest_framework.filters import OrderingFilter
class BooksView(ViewSetMixin, ListAPIView):
queryset = Book.objects
serializer_class = BookSerializers
authentication_classes = []
permission_classes = []
throttle_classes = []
filter_backends = [OrderingFilter]
# search_fields = ['name']
# filterset_fields = ['name']
ordering_fields = ['price'] # 这个看下OrderingFilter源码就能找出这个字段
# 支持的查询方法:
http://127.0.0.1:8000/api/v1/books/?ordering=price
http://127.0.0.1:8000/api/v1/books/?ordering=-price # 倒序
http://127.0.0.1:8000/api/v1/books/?ordering=price,-id # 支持同时排,如果价格一样,就按id排序(自己想怎么定就怎么定)
六、分页
1.作用
主要用于查所有
2.使用方法
# drf内置了三个分页器,对应三种分页方式
#内置的分页类不能直接使用,需要继承,定制一些参数后才能使用
# 分页使用,自定义一个分页类(三种)
第一种,常用,网页常用
class CommonPageNumberPagination(PageNumberPagination):
page_size = 2 # 每页显示2条
page_query_param = 'page' # 前端分页带着的那个名字 page=10意思就是查询第10页的数据
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' # 排序字段
# 配置在视图类上即可
class BookView(ViewSetMixin, ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = []
authentication_classes = []
throttle_classes = []
# 之前的东西一样用 ,内置的分页类不能直接使用,需要继承,定制一些参数后才能使用
# pagination_class = PageNumberPagination
#基本分页方式(基本是这种,网页端):http://127.0.0.1:8000/api/v1/books/?page=2&size=3
# pagination_class = LimitOffsetPagination
# 偏移分页 http://127.0.0.1:8000/api/v1/books/?limit=4&offset=1
# 从第一条开始,取4条
pagination_class = CommonCursorPagination
# 游标分页,只能下一页,上一页,不能跳到中间,但它的效率最高,大数据量分页,使用这种较好
今日注意
1.如果模型层,某个字段用了CHOICE,Choice((),()),里面放元组,用来限制用户做出的选择
就可以通过 get_属性_display()方法取display_name
注意啊!INT Char 两种字段到时候拿小元组内的前面的数字时,CharField是字符串形式的数字!!!
2.模型层,如果字段是CharField,不支持神奇双下的__gt __lt之类的
3.print(request.META.get('REMOTE_ADDR'))可以拿到请求头的IP地址!
4.今天学的三大认证,或者说以后在django配置中配置,都不要先导入,直接用app01.自己写的py文件.自己创的类
5.对查所有图书类使用分页时,发现queryset必须.all()前面我都是省了的,因为GenericAPIView自己点了all()
今日单词
throttling 节流,掐断的名词 是频率的关键字
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)