首页 > 其他分享 >DRF

DRF

时间:2022-10-10 22:01:25浏览次数:45  
标签:return price queryset page class self DRF

DRF频率类

# 某个接口,限制访问频率----》可以根据IP,用户id
# 频率类的编写
    -第一步:写一个类,继承SimpleRateThrottle
    -第二步:重写get_cache_key方法
    -第三步:返回什么,就以什么做限制
    -第四步:写一个类属性
        -scope = '3_min'
    -第五步:配置文件中配置
        REST_FRAMEWORK = {
            # 频率类中scope对应的值
            '3_min':'3/m'   # 数字/s m h  d
        }
        
   -第六步:局部和全局使用
    局部用:视图类中
        class BookView(APIView):
            throttle_classes = [IPThrottle, ]
    全局用:配置文件
        REST_FRAMEWORK = {
            "DEFAULT_THROTTLE_RATES": {
                # 频率类中scope对应的值
                '3_min': '3/m'  # 数字/s m h  d
            },
            'DEFAULT_THROTTLE_CLASSES':['app01.throttling.IPThrottle',]
        }

频率类

class IPThrottle(SimpleRateThrottle):
    # 写一个类属性,字符串
    scope = '3_min'
    def get_cache_key(self, request, view):
        # return 什么就一什么做限制, 返回ip   返回用户id
        return request.META.get('REMOTE_ADDR')
        # return request.user.id  # 返回用户id

视图类

class BookView(APIView):
    throttle_classes = [IPThrottle, ]

    def get(self, request):
        return Response('ok')

    def throttled(self, request, wait):
        from rest_framework.exceptions import Throttled
        class MyThrottled(Throttled):
            default_detail = '超限制乐'
            extra_detail_singular = '还有 {wait} 描述.'
            extra_detail_plural = '出了 {wait} 秒.'

        raise MyThrottled(wait)

配置文件

REST_FRAMEWORK = {
    "DEFAULT_THROTTLE_RATES": {
        # 频率类中scope对应的值
        '3_min': '3/m',  # 数字/s m h  d
        'anon':'4/h',
        'user':'5/m'
    },
    'DEFAULT_THROTTLE_CLASSES':['app01.throttling.IPThrottle',]

}

DRF内置认证类、权限类、频率类

# 内置的认证---》跟咱们项目都补贴和,咱们不用,咱们自己根据自己的规则写
    -SessionAuthentication:之前老的session认证登录方式用,后期都不用了
    -BasicAuthentication :基本认证方式,咱们不用
    -TokenAuthentication :使用token认证方式,有用,但是咱们也是自己写的
    
    
# 内置的权限类
    -IsAdminUser :校验是不是auth的超级管理员权限
    -IsAuthenticated:后面会用到,验证用户是否登录了,登录了才有权限,没登录就没有权限
    -IsAuthenticatedOrReadOnly:知道有这个东西即可
    
# 内置的频率类
    -UserRateThrottle :限制登录用户的频率,需要配置配置文件
    -AnonRateThrottle:登录用户不限制,未登录用户限制,需要配置配置文件

DRF排序

# 排序功能接口只针对于:获取所有接口

# 继承了GenericAPIView的视图类,只要加入,两个类属性
class BookView(GenericViewSet, ListModelMixin):
    serializer_class = BookSerializer
    queryset = Book.objects.all()

    filter_backends = [OrderingFilter, ]
    ordering_fields = ['price','id' ]
# 访问的时候
http://127.0.0.1:8000/api/v1/books?ordering=price  # 按price升序
http://127.0.0.1:8000/api/v1/books?ordering=-price # 按price降序
http://127.0.0.1:8000/api/v1/books?ordering=price,id # 先按价格升序排,价格一样,再按id升序排

DRF过滤

#  查询名字为XXX的所有图书:获取所有接口

# 内置的过滤使用---》不能指定查询那个字段,模糊查询
    -继承了GenericAPIView的视图类,只要加入,两个类属性
    class BookView(GenericViewSet, ListModelMixin):
        serializer_class = BookSerializer
        queryset = Book.objects.all()

        filter_backends = [SearchFilter,]
        search_fields=['name','price']  # 按name或price过滤
    -使用
        http://127.0.0.1:8000/api/v1/books?search=XXX
        # search= xx ----》具体查询是  name like xx or price like xx
        
# 我们想http://127.0.0.1:8000/api/v1/books?name=XXX&price=12---》第三方django-filter
    -安装:pip3 install django-filter
    
    -继承了GenericAPIView的视图类,只要加入,两个类属性
         from django_filters.rest_framework import DjangoFilterBackend
         class BookView(GenericViewSet, ListModelMixin):
            serializer_class = BookSerializer
            queryset = Book.objects.all()

            filter_backends = [DjangoFilterBackend, ]
            filter_fields = ['name', 'price']
    
    -使用
    http://127.0.0.1:8000/api/v1/books?name=XXX&price=11

    
    
  # 自定义过滤器---》完成更多查询操作
    -写一个类,继承BaseFilterBackend
    -重写filter_queryset方法
    -配置在视图类中
    from .throttling import FilterName
    class BookView(GenericViewSet, ListModelMixin):
        serializer_class = BookSerializer
        queryset = Book.objects.all()

        filter_backends = [FilterName, ]
        
        
        
  # 既有过滤又有排序
    class BookView(GenericViewSet, ListModelMixin):
        serializer_class = BookSerializer
        queryset = Book.objects.all()
        filter_backends = [FilterName, OrderingFilter]
        ordering_fields = ['price', ]
        
# 源码分析,为什么这么配置就生效

    -GenericAPIView的方法
    def filter_queryset(self, queryset):
        for backend in list(self.filter_backends):
            queryset = backend().filter_queryset(self.request, queryset, self)
        return queryset

DRF自定义频率类

'''
自定义的逻辑:
-(1)取出访问者ip {192.168.1.12:[访问时间3,访问时间2,访问时间1],192.168.1.12:[],192.168.1.14:[]}
​ -(2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
​ -(3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
​ -(4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
​ -(5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
'''
from rest_framework.throttling import BaseThrottle
class MyThrottling():
    VISIT_RECORD = {}

    def __init__(self):
        self.history = None
    def allow_request(self, request, view):
        # (1)取出访问者ip
        ip = request.META.get('REMOTE_ADDR')
        import time
        ctime = time.time()
        # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问
        if ip not in self.VISIT_RECORD:
            self.VISIT_RECORD[ip] = [ctime, ]
            return True
        self.history = self.VISIT_RECORD.get(ip)
        # (3)循环判断当前ip的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
        while self.history and ctime - self.history[-1] > 60:
            self.history.pop()
        # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
        # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败
        if len(self.history) < 3:
            self.history.insert(0, ctime)
            return True
        else:
            return False

    def wait(self):
        import time
        ctime = time.time()
        return 60 - (ctime - self.history[-1])

DRF三种分页方式

 

PageNumberPagination---基本分页

 

前端访问网址形式:GET http://127.0.0.1:8000/students/?page=4

可以在子类中定义的属性:

  • page_size 每页数目
  • 前端访问网址形式:page_query_param 前端发送的页数关键字名,默认为”page”
  • page_size_query_param 前端发送的每页数目关键字名,默认为None
  • max_page_size 前端最多能设置的每页数量
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination

class BookPagination(PageNumberPagination):
    page_size = 2  # 默认每页展示的条数
    page_query_param = 'page'  # 查询页码的参数
    page_size_query_param = 'size'  # 控制每页显示的条数 ?size=3
    max_page_size = 5  # 控制每页最多显示多少条数

 

LimitOffsetPagination---偏移分页

前端访问网址形式:GET http://127.0.0.1/four/students/?limit=100&offset=400

可以在子类中定义的属性:

  • default_limit 默认限制,默认值与PAGE_SIZE设置一直
  • limit_query_param limit参数名,默认’limit’
  • offset_query_param offset参数名,默认’offset’
  • max_limit 最大limit限制,默认None
class CommonLimitOffsetPagination(LimitOffsetPagination):
    default_limit = 2    # 每页显示多少条
    limit_query_param = 'limit'   # 取多少条
    offset_query_param = 'offset' #从第0个位置偏移多少开始取数据
    max_limit = 5     # 最大限制条数

 CursorPagination---游标分页

前端访问网址形式:GET http://127.0.0.1/four/students/?cursor=cD0xNQ%3D%3D

可以在子类中定义的属性:

  • cursor_query_param:默认查询字段,不需要修改
  • page_size:每页数目
  • ordering:按什么排序,需要指定
class CommonCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'  # 查询的名字  等同于  page=xx
    page_size = 3  # 每页显示多少条
    ordering = 'id'  # 排序规则,必须是表中有的字段,一般用id

继承APIView实现分页

from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet
from rest_framework.response import Response
class BookView(ViewSet):
    def list(self,request):
        books=Book.objects.all()
        # 分页
        # paginator=PageNumberPagination()
        paginator=CommonLimitOffsetPagination()  # 实例化自己写的分页类
        #分页过后的数据
        qs=paginator.paginate_queryset(books,request,self)
        #序列化
        ser=BookSerializer(qs,many=True)
        # 第一种方式:每页总条数,上一页,下一页
        # return Response(ser.data)
        # 第二种:自己凑
        # return Response({
        #     'count':books.count(),
        #     'next': paginator.get_next_link(),
        #     'previous':paginator.get_previous_link(),
        #     'results': ser.data
        # })
        # 第三种;直接使用分页类的方法
        return paginator.get_paginated_response(ser.data)

 

标签:return,price,queryset,page,class,self,DRF
From: https://www.cnblogs.com/-sunflower-/p/16777561.html

相关文章

  • drf 之分页,过滤,排序
    自定义频率类classMyThrottle(SimpleRateThrottle):VISIT_RECORD={}#存放用户访问记录{ip1:[时间1,时间2].。。}def__init__(self):self.hi......
  • drf学习笔记
    今日内容概要权限类使用频率类使用认证类源码分析权限类源码分析部分频率类源码分析鸭子类型今日内容详细权限类使用第一步:写一个类,继承BasePermission第......
  • 【2022.10.9】drf(7)
    今日内容1.权限类使用2.频率类使用3.认证源码分析4.权限源码分析5.简单读写频率类源码6.鸭子类型1权限类使用#认证:校验用户是否登录,登录认证#用户登录了,某个......
  • drf三大认证之权限源码解析
    1.认证,频率,权限的源码解读入口就是APIView源码的dispatch方法的三大认证,全局异常处理self.initial(request,*args,**kwargs)2.查看APIView的initial里面的三句代......
  • drf学习-7
    一、内容回顾1、drf路由的使用  路由有三种写法    -视图类.as_view    -视图类.as_view({'get':'list'})    -自动生成路由      导入——实例......
  • 【2022-10-09】DRF从入门到入土(七)
    drf组件之权限类使用#认证:校验用户是否登录,登录认证#用户登录了,某个接口可能只有超级管理员才能访问,普通用户不能访问#出版社的所有接口,必须登录,而且是超级管理员才......
  • drf三大认证(认证,权限,频率)及其源码分析
    drf三大认证之认证drf三大认证之权限drf三大认证之频率drf三大认证之认证源码分析drf三大认证之权限源码分析鸭子类型drf三大认证之认证  访问接......
  • drf -三大权限认证例子
    三大权限认证测试例子代码models.pyfromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):name=models.CharField(max_length=3......
  • drf之权限类与频率类
    一、权限类#权限就是我们在登入之后我们在访问这个接口的时候有没有访问的权限#eg:现在我们把用户等级分为两个等级,一个为vip用户,一个为普通用户然......
  • drf——源码分析
    drf——源码分析认证源码分析权限源码分析频率类源码分析三大认证的源码分析之前读取的APIView的源码的执行流程中包装了新的request,执行了三大认证,执行视图类的......