• Rest_framework之版本控制、响应器和分页器


    一、访问频率补充

    频率:
    自定义:
    1 定义一个类MyThrottles
    allow_request(频率限制的逻辑) ==》这两个函数都是派生出来的,继承的类里面封装的。
    wait(返回一个数字,给用户提示,还差多少秒)
    2 局部使用:throttle_classes=[MyThrottles,]
    3 全局使用:'DEFAULT_THROTTLE_CLASSES':['utils.common.MyThrottles',],
    用内置的:(可以控制ip,和userid)
    1 写一个类,继承SimpleRateThrottle
    属性:scope = 'xxx'  ===》scope是源码里的参数,必须要写
    重写方法:get_cache_key

     1 from rest_framework.throttling import SimpleRateThrottle
     2 
     3 
     4 class VisitThrottle(SimpleRateThrottle):
     5     # {IP:[]}
     6     # {id:[]}
     7     scope = 'xxx'  # 这个必须要写 因为源码里有
     8 
     9     def get_cache_key(self, request, view):  # 重写get_cache_key方法
    10         # ip=request.META.get('REMOTE_ADDR')  根据IP来限制访问频率 remote_addr如果是用的代理,获取的是代理IP,否则是主机的IP
    11         # 用户一分钟只能访问5次
    12         pk = request.user.pk  # 根据用户的主键限制访问频率,默认是通过IP限制,可看源码
    13         return pk

    去setting里配置:'DEFAULT_THROTTLE_RATES':{
    # 'xxx':'5/m',  ===》这里的xxx是scope设定的值。
    'xxx':'5/m',
    }
    2 局部使用:throttle_classes=[MyThrottles,]
    3 全局使用:'DEFAULT_THROTTLE_CLASSES':['utils.common.MyThrottles',],
    补充:
    认证,想局部取消(禁用)===》只需要在认证的地方加上下面的:
      authentication_classes=[]

    同一个ip一分钟内只能访问三次
        {ip1: [12:01:20,12:01:04,12:01:00],ip2: [],ip3: [],}
    #(1)取出访问者ip
    # (2)判断当前ip不在访问字典里,添加进去,并且直接返回True,表示第一次访问,在字典里,继续往下走
    #现在是12:01:30
    # (3)循环判断当前时间的列表,有值,并且当前时间减去列表的最后一个时间大于60s,把这种数据pop掉,这样列表中只有60s以内的访问时间,
    # (4)判断,当列表小于3,说明一分钟以内访问不足三次,把当前时间插入到列表第一个位置,返回True,顺利通过
    # (5)当大于等于3,说明一分钟内访问超过三次,返回False验证失败

    代码演示如下:

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


    二、版本控制:
    1 127.0.0.1/course/?version=v100000   ===》常用的两种版本书写方式,url带参数形式的

    versioning_class = QueryParameterVersioning   只能写成这种形式的,因为源码里不是和处理以前列表形式一样来处理这个


    用from rest_framework.versioning import QueryParameterVersioning
    在视图类里:
    versioning_class=QueryParameterVersioning(**不再是列表)
    在setting里配置:
    REST_FRAMEWORK={
    'VERSION_PARAM':'version',
    'DEFAULT_VERSION':'v2',
    'ALLOWED_VERSIONS':['v1','v2']
    }
    视图类里:
    request.version  ===》 版本号

    127.0.0.1/v1/course/   ===》这种形式比较常用 

    versioning_class = URLPathVersioning   


    用from rest_framework.versioning import URLPathVersioning
    在视图类里:
    versioning_class=URLPathVersioning**不再是列表)
    在setting里配置:
    REST_FRAMEWORK={
    'VERSION_PARAM':'version',
    'DEFAULT_VERSION':'v2',
    'ALLOWED_VERSIONS':['v1','v2']
    }
    视图类里:
    request.version

    3 反向解析(了解)

    urls

     1 from django.conf.urls import url
     2 from django.contrib import admin
     3 from app01 import views
     4 urlpatterns = [
     5     url(r'^admin/', admin.site.urls),
     6     url(r'^testversion/', views.Test.as_view()),
     7     url(r'^(?P<version>[v1|v2|v3]+)/testversion/', views.Test2.as_view(),name='ttt'),
     8     url(r'^testres', views.Test3.as_view()),
     9     url(r'^page', views.Page.as_view()),
    10 ]

    settings里相关配置

    1 REST_FRAMEWORK={
    2     'VERSION_PARAM':'version',
    3     'DEFAULT_VERSION':'v2',
    4     'ALLOWED_VERSIONS':['v1','v2']
    5 }

    views

     1 from django.shortcuts import render, HttpResponse
     2 
     3 # Create your views here.
     4 from app01 import models
     5 from rest_framework.views import APIView
     6 from rest_framework.response import Response
     7 
     8 from rest_framework.versioning import QueryParameterVersioning, URLPathVersioning
     9 
    10 版本控制
    11 class Test(APIView):
    12     versioning_class = QueryParameterVersioning
    13 
    14     def get(self, request, *args, **kwargs):
    15         print(request.version)
    16 
    17         return Response('ok')
    18 
    19 
    20 from django.urls import reverse
    21 
    22 反向解析  仅作了解 用的比较少
    23 class Test2(APIView):
    24     versioning_class = URLPathVersioning
    25 
    26     def get(self, request, *args, **kwargs):
    27         print(request.version)
    28         url = request.versioning_scheme.reverse(viewname='ttt', request=request)
    29         print(url)
    30         url2 = reverse(viewname='ttt', kwargs={'version': 'v1'})
    31         print(url2)
    32 
    33         return Response('ok ttest2')


    三、响应器:
    以后项目中用:(返回的格式,只是json格式)
    REST_FRAMEWORK={
    'DEFAULT_RENDERER_CLASSES':['rest_framework.renderers.JSONRenderer',],
    }
    补充一点:
    查找模板的时候:先从自己app里找,找不到去项目,再找不到,去各个app里找

     views

     1 from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer, AdminRenderer
     2 
     3 
     4 class Test3(APIView):
     5     renderer_classes=[BrowsableAPIRenderer]
     6     def get(self, request, *args, **kwargs):
     7         return Response({
     8             'name': 'qlz',
     9             'age': 18,
    10             'name1': 'qlz',
    11             'age2': 18,
    12         })

    settings

    REST_FRAMEWORK = {
        'DEFAULT_RENDERER_CLASSES': ['rest_framework.renderers.JSONRenderer'],
     
    }

    四、分页

    1 简单分页
    127.0.0.1/course/page=3
    PageNumberPagination
    #每页显示多少条api_settings.PAGE_SIZE
    #page_size =
    #查询指定页码的重命名
    #page_query_param = 'page'
    #指定每页显示条数
    #page_size_query_param = None
    #限制每页显示最大条数
    #max_page_size = None

    2 偏移分页
    127.0.0.1/course/offset=10&limit=5
    LimitOffsetPagination
    # default_limit:默认显示多少条
    # max_limit:最大显示多少条
    # limit_query_param:重新命名limit(limit=4:表明显示四条,受max_limit的限制)
    # offset_query_param:指定查询的标杆名(offset=1:表明从第二条开始,往后偏移)
    3 加密分页
    后台返回的url:127.0.0.1/course/page=dfgeg
    CursorPagination
    cursor_query_param = 'cursor':查询的名字
    page_size = api_settings.PAGE_SIZE:每页显示的条数
    ordering = '-created' :按谁排序

    补充:(1)修改数据属性的方式:
    1 再setting里配置每页条数
    2 写一个类,继承它,属性重写
    3 再对象里修改
    (2)my_page.get_paginated_response(ser.data)
    # 对Response做了封装,返回内容里有总条数,上一页,下一页的链接

    views

     1 from rest_framework.serializers import ModelSerializer
     2 from rest_framework import serializers
     3 
     4 
     5 class BookSer(serializers.ModelSerializer):
     6     class Meta:
     7         model = models.Book
     8         fields = '__all__'
     9 
    10 
    11 from rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPagination
    12 
    13 
    14 # class Page(APIView):
    15 #     def get(self,request,*args,**kwargs):
    16 #         ret=models.Book.objects.all()
    17 #         my_page=PageNumberPagination()
    18 #         my_page.page_size=2
    19 #         my_page.page_size_query_param='size'
    20 #         my_page.max_page_size=5
    21 #
    22 #         page_list=my_page.paginate_queryset(ret,request,self)
    23 #         ser=BookSer(instance=page_list,many=True)
    24 #         # 1 再setting里配置每页条数
    25 #         # 2 写一个类,继承它,属性重写
    26 #         # 3 再对象里修改
    27 #         '''
    28 #         每页显示多少条api_settings.PAGE_SIZE
    29 #         page_size =
    30 #         查询指定页码的参数
    31 #         page_query_param = 'page'
    32 #         指定每页显示条数
    33 #         page_size_query_param = None
    34 #         限制每页显示最大条数
    35 #         max_page_size = None
    36 #         '''
    37 #
    38 #         return Response(ser.data)
    39 
    40 # class Page(APIView):
    41 #     def get(self,request,*args,**kwargs):
    42 #         ret=models.Book.objects.all()
    43 #         my_page=LimitOffsetPagination()
    44 #         my_page.default_limit=3
    45 #         my_page.max_limit=5
    46 #
    47 #
    48 #         page_list=my_page.paginate_queryset(ret,request,self)
    49 #         ser=BookSer(instance=page_list,many=True)
    50 #         # 1 再setting里配置每页条数
    51 #         # 2 写一个类,继承它,属性重写
    52 #         # 3 再对象里修改
    53 #         '''
    54 #         default_limit:默认显示多少条
    55 #         max_limit:最大显示多少条
    56 #         limit_query_param:重新命名limit(limit=4:表明显示四条,受max_limit的限制)
    57 #         offset_query_param:指定查询的标杆名(offset=1:表明从第二条开始,往后偏移)
    58 #         '''
    59 #
    60 #         # return Response(ser.data)
    61 #         # 对Response做了封装,返回内容里有总条数,上一页,下一页的链接
    62 #         return my_page.get_paginated_response(ser.data)
    63 
    64 
    65 class Page(APIView):
    66     def get(self, request, *args, **kwargs):
    67         ret = models.Book.objects.all()
    68         my_page = CursorPagination()
    69         my_page.ordering = 'id'
    70         my_page.page_size = 2
    71         page_list = my_page.paginate_queryset(ret, request, self)
    72         ser = BookSer(instance=page_list, many=True)
    73         # 1 再setting里配置每页条数
    74         # 2 写一个类,继承它,属性重写
    75         # 3 再对象里修改
    76         '''
    77             cursor_query_param = 'cursor':查询的名字
    78             page_size = api_settings.PAGE_SIZE:每页显示的条数
    79             ordering = '-created'  :按谁排序
    80         '''
    81 
    82         # return Response(ser.data)
    83         # 对Response做了封装,返回内容里有总条数,上一页,下一页的链接
    84         return my_page.get_paginated_response(ser.data)
    85         # return Response(ser.data)
    Views

    自己封装response对象
    。。。。



    作业:
    1 前端操作cookie
    2 频率显示中文(去源码里找,替换)
    3 版本控制,不在setting里配置,实现
    5 redis安装上(windows/linux)
    4 axios
    5 cc视频 ==》路飞学城用的视频代理,现在一般不自己搞代理,浪费人力物力,买的代理划算。

  • 相关阅读:
    MySQL主从.md
    mysqldump.md
    MySQL管理.md
    SQL语句.md
    如何在同一台服务器上部署两个tomcat
    loadrunner函数解密之web_reg_save_param
    loadrunner函数解密之web_reg_find
    Jmeter如何保持cookie,让所有请求都能用同一个cookie,免去提取JSESSIONID
    Jmeter如何提取响应头部的JSESSIONID
    Loadrunner如何进行有效的IP欺骗
  • 原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9837951.html
Copyright © 2020-2023  润新知