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]
  1. 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   节流,掐断的名词  是频率的关键字
posted @   yiwufish  阅读(95)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示