DRF学习笔记(5)——节流、分页、过滤、生成接口文档

节流

节流类似于权限,⽤于控制客户端可以对API发出的请求的速率。

自定义类

继承自SimpleRateThrottle,要在里面设置rate和重写get_cache_key(self, request, view)

App\MyThrottle.py
from rest_framework.throttling import SimpleRateThrottle
class MyThrottle(SimpleRateThrottle):
    rate = '5/m'  # 请求次数/时间段 (s,m,h,d)
    def get_cache_key(self, request, view):
        #根据用户ID,登录不限制,不登录限制每分钟5次
        if request.user and request.user.id:
            return None  # 返回None,没有次数限制
        else:
            return 1   # 未登录用户
局部限制
views.py
class UserInfoView(GenericAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    # 局部认证,只针对当前类
    authentication_classes = (MyAuthentaion,)
    # 节流
    throttle_classes = (MyThrottle,)
    lookup_field = 'pk'
    def get(self,request,pk):
        obj = self.get_object()  # 获取对象
        us = UserSerializer(instance=obj)  # 序列化
        return Response(us.data)

上述视图实现了对登陆后(通过认证)的用户无访问限制,对未登录用户/token过期用户 限制为访问每分钟5次。
在这里插入图片描述

全局限制
使用自定义节流类
  • 在自定义节流类中设置一个scope。
    scope = 'MyThrottle'
  • setting设置
REST_FRAMEWORK = {
# 对所有接口限制
        'DEFAULT_THROTTLE_CLASSES': ['App.MyThrottle.MyThrottle'],
}
使用DRF提供的节流类
  • setting设置
REST_FRAMEWORK = {
# 对所有接口限制
	'DEFAULT_THROTTLE_CLASSES': ['rest_framework.throttling.AnonRateThrottle'],
	'DEFAULT_THROTTLE_RATES': {
	        'anon': '2/day',# 匿名用户
     },
}
可选节流类
  • AnonRateThrottle
    限制所有匿名未认证⽤户,使⽤IP区分⽤户。
    使⽤ DEFAULT_THROTTLE_RATES[‘anon’] 来设置频次
  • UserRateThrottle
    限制认证⽤户,使⽤User id 来区分。
    使⽤ DEFAULT_THROTTLE_RATES[‘user’] 来设置频次
  • ScopedRateThrottle
    限制⽤户对于每个视图的访问频次,使⽤ip或user id。

分页

系统提供的可选分页器
PageNumberPagination
  • 前端访问形式GET http://api.example.org/books/?page=4
  • 可定义属性
    • page_size 每⻚数⽬
    • page_query_param 前端发送的⻚数关键字名,默认为"page"
    • page_size_query_param 前端发送的每⻚数⽬关键字名,默认为None
    • max_page_size 前端最多能设置的每⻚数量
LimitOffsetPagination
  • 前端访问形式GET http://api.example.org/books/?limit=100&offset=400
  • 可定义属性
    • default_limit 默认限制,默认值与 PAGE_SIZE 设置⼀直
    • limit_query_param limit参数名,默认’limit’
    • offset_query_param offset参数名,默认’offset’
    • max_limit 最⼤limit限制,默认None
全局分页

在setting.py里进行设置。

REST_FRAMEWORK = {
	 'DEFAULT_PAGINATION_CLASS':
	'rest_framework.pagination.PageNumberPagination',
	 'PAGE_SIZE': 10 # 每⻚数⽬
}

http://127.0.0.1:8000/book/?page=2&page_size=3
在这里插入图片描述

自定义类

自定义分页要重写get_paginated_response(self, data)方法,

class BookListPager(PageNumberPagination):
    page_size = 3  # 每页3条记录
    page_size_query_param = 'page_size'    # 每页记录数的参数名字

    # 自定义分页形式
    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('count', self.page.paginator.count),
            ('page_range', list(self.page.paginator.page_range)),  # 页码范围
            ('has_next', self.page.has_next()),
            ('has_prious', self.page.has_previous()),
            ('next_page_number', self.page.next_page_number()),
            ('results', data)
        ]))
针对视图写分页
views.py
class BookListView(GenericAPIView):
    queryset = Bookinfo.objects.all()
    serializer_class = BookinfoSerializer
    pagination_class = BookListPager

    def get(self,request,*args,**kwargs):
        # 过滤结果集
        queryset = self.filter_queryset(self.get_queryset())
        # 系统实现分页,获取分页对象
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        # page为None,不分页,返回所有数据
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

或者是直接继承ListAPIView,父类已经写好相关的方法。

class BookListView(ListAPIView):
    queryset = Bookinfo.objects.all()
    serializer_class = BookinfoSerializer
    pagination_class = BookListPager

在这里插入图片描述

过滤

  • 使用django-filter 第三方应用
  • setting配置
INSTALLED_APPS = [
 ...
 'django_filters', # 需要注册应⽤,
]
REST_FRAMEWORK = {
 'DEFAULT_FILTER_BACKENDS': ('django_filters.rest_framework.DjangoFilterBackend',)
}
简单配置
class BooksView(ListAPIView):
    queryset = Bookinfo.objects.all()
    serializer_class = BookinfoSerializer
    # 过滤字段
    filter_fields = ('btitle', 'bread')
  • 这种方式只能使用等于,如果要有大于,小于,包含等过滤,需要自定义过滤器
    在这里插入图片描述
自定义过滤器
  • 使用条件字典
App\MyFilters.py
class BookFilter(filters.FilterSet):
    class Meta:
        model = Bookinfo
        fields = {
            # 运算符和ORM中一样
            # http://127.0.0.1:8000/list/?btitle__icontains=%E4%BD%99
            'btitle': ['icontains', 'startswith', 'iendswith'],  # 不区分大小写的包含,开头,结尾
            'bcomment': ['lt', 'gt'],  #
            'bread': ['lte', 'gte', 'in'],
            'bpub_date': ['exact', 'gt', 'year__lt', 'year__gt'],
            'bimage': ['isnull']
        }
views.py
class BooksView(ListAPIView):
    queryset = Bookinfo.objects.all()
    serializer_class = BookinfoSerializer
    filter_class = BookFilter

在这里插入图片描述

  • 自定义查询方法
App\MyFilters.py
class BookFilter(filters.FilterSet):
    class Meta:
        model = Bookinfo
        fields = {
            # 运算符和ORM中一样
            # http://127.0.0.1:8000/list/?btitle__icontains=%E4%BD%99
            'btitle': ['icontains', 'startswith', 'iendswith'],  # 不区分大小写的包含,开头,结尾
            'bcomment': ['lt', 'gt'],  #
            'bread': ['lte', 'gte', 'in'],
            'bpub_date': ['exact', 'gt', 'year__lt', 'year__gt'],
            'bimage': ['isnull']
        }
	# 查询字段名不要求和模型中一模一样
    # field_name 模型中的字段名
    # method 查询方法
    # http://127.0.0.1:9090/list/?comment=50
    comment = filters.NumberFilter(field_name='bcomment', method='find_comment')
    def find_comment(self, queryset, name, value):
        return queryset.filter(bcomment__lt=value)

在这里插入图片描述
参考:django_filters

生成接口文档

  • 安装依赖
    pip install coreapi
  • setting.py
REST_FRAMEWORK = {
	 'DEFAULT_SCHEMA_CLASS':
	'rest_framework.schemas.coreapi.AutoSchema'
}
  • 总路由中添加路径
from rest_framework.documentation import include_docs_urls
urlpatterns = [
 ...
 path('docs/', include_docs_urls(title='My API title'))
]
  • 视图设置
    文档描述说明定义
# 视图
class BookListCreateView(generics.ListCreateAPIView):
 """
 get:
 返回所有图书信息.
 post:
 新建图书.
 """

# 视图集
class BookInfoViewSet(mixins.ListModelMixin,
mixins.RetrieveModelMixin, GenericViewSet):
 """
 list:
 返回图书列表数据
 retrieve:
 返回图书详情数据
 latest:
 返回最新的图书数据
 read:
 修改图书的阅读量
 """
  • 访问接口文档网页
    127.0.0.1:8000/docs/
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值