drf - 偏移分页组件 LimitOffsetPagination
时间:2019-09-15
本文章向大家介绍drf - 偏移分页组件 LimitOffsetPagination,主要包括drf - 偏移分页组件 LimitOffsetPagination使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
数据准备
model.py文件
定义两个表Car表和Brand表,其中Car中的brand字段外键关联Brand表
from django.db import models
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True)
class Meta:
abstract = True
class Car(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=5, decimal_places=2)
brand = models.ForeignKey('Brand', db_constraint=False, on_delete=models.DO_NOTHING, related_name='cars')
@property
def brand_name(self):
return self.brand.name
class Meta:
db_table = 'old_boy_car'
verbose_name = '汽车'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Brand(BaseModel):
name = models.CharField(max_length=32)
class Meta:
db_table = 'old_boy_brand'
verbose_name = '品牌'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
新建的serializer.py文件
brand字段只参与反序列化,brand_name只参与序列化
from rest_framework.serializers import ModelSerializer
from . import models
class CarModelSerializer(ModelSerializer):
class Meta:
model = models.Car
fields = ('name','price','brand','brand_name')
extra_kwargs = {
"brand":{
'write_only':True
},
'brand_name':{
'read_only':True
},
}
分页组件部分源码分析一
通常是在获取多条数据list方法中,进行分页显示。所以viewsets.py文件中list方法是分页入口
class ListModelMixin:
def list(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)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
1. 先调用paginate_queryset方法,此方法继承至generics中的GenericAPIView类
def paginate_queryset(self, queryset):
"""
Return a single page of results, or `None` if pagination is disabled.
"""
if self.paginator is None: # self.paginator分页器,如果为None表示不分页
return None
return self.paginator.paginate_queryset(queryset, self.request, view=self)
2. 调用paginator方法
@property
def paginator(self):
"""
The paginator instance associated with the view, or `None`.
"""
if not hasattr(self, '_paginator'):
# 如果配置中的pagination_class为空就不分页,所以要分页就需要配置pagination_class类,else中实例化分页类
if self.pagination_class is None:
self._paginator = None
else:
self._paginator = self.pagination_class()
return self._paginator
3. 自定义pagination_class
4. 调用pagination_class类中的paginate_queryset方法
自定义分页组件
新建的paginations.py文件,CarPageNumberPagination继承了drf分页组件中的PageNumberPagination类
from rest_framework.pagination import LimitOffsetPagination
class CarLimitOffsetPagination(LimitOffsetPagination):
default_limit = 3 # 设置每页显示的数量为3,此时url中下一页的offset就会往后偏移3条
# 优先使用limit_query_param来设置显示条数
limit_query_param = 'limit'
offset_query_param = 'offset' # 偏移数,就是多少条数据后显示
max_limit = 5
# url链接:car/?limit=2 一页显示2条,默认显示第一页
# url链接:car/?limit=2&offset=4 往后偏移4条数据后,再显示自定义的2条数据,limit输入的数不能大于max_limit设置的数,大于则按max_limit来显示
注意:car/?limit=2&offset=4,若数据总条数只有5条,偏移offset=4条后显示就只显示1条数据
view.py文件:需要自定义pagination_class
from rest_framework.viewsets import ModelViewSet
from . import models, serializer
from .paginations import CarLimitOffsetPagination
class CarModelViewSet(ModelViewSet):
queryset = models.Car.objects.filter(is_delete=False)
serializer_class = serializer.CarModelSerializer
# 自定义pagination_class
parser_classes = CarLimitOffsetPagination
分页组件部分源码分析二
1. 调用CarLimitOffsetPagination的paginate_queryset方法(继承至LimitOffsetPagination)
def paginate_queryset(self, queryset, request, view=None):
self.count = self.get_count(queryset) # 获取数据的总数量
self.limit = self.get_limit(request)
if self.limit is None:
return None
self.offset = self.get_offset(request)
self.request = request
if self.count > self.limit and self.template is not None:
self.display_page_controls = True
if self.count == 0 or self.offset > self.count:
return []
return list(queryset[self.offset:self.offset + self.limit])
2. 调用 get_limit 方法获取 limit
def get_limit(self, request):
if self.limit_query_param: # limit_query_param 为'limit'
try:
return _positive_int(
request.query_params[self.limit_query_param],
strict=True,
cutoff=self.max_limit # 最大limit
)
except (KeyError, ValueError):
pass
return self.default_limit # drf中默认设置为None,可以在类中配置
3. 设置了limit_query_param时,self.limit 为调用_positive_int方法后的结果
def _positive_int(integer_string, strict=False, cutoff=None):
"""
Cast a string to a strictly positive integer.
"""
ret = int(integer_string) # url传入的值,在url中:car/?limit=4.则ret=4
if ret < 0 or (ret == 0 and strict):
raise ValueError()
if cutoff:
return min(ret, cutoff)
return ret
4. 调用 get_offset方法获取 offset
def get_offset(self, request):
try:
return _positive_int(
request.query_params[self.offset_query_param], # offset_query_param = 'offset'
)
except (KeyError, ValueError):
return 0
原文地址:https://www.cnblogs.com/863652104kai/p/11523548.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Rust日报】2020-09-05 微软在c++静态分析工具实现了一些rust的安全规则
- 一起来玩玩WebGL
- 自研网关:多项目的swagger聚合功能
- Prometheus 如何做到“活学活用”,大牛总结的避坑指南
- 文档驱动 —— 表单组件(一):表单元素组件 优点缺点选择文本类的Inputcheck 多选value的类型问题
- Vue3.0源码结构分析
- 【每周一库】- cached - 缓存结构型、辅助函数记忆化
- meta生成器 —— 表单元素组件 meta表单代码meta的模板data变幻
- 不用写代码也能做表单 —— 加载meta即可 菜单表单加载json运行效果。ModelAbout
- 从0到1,手把手教你入门 etcd
- 数据结构:手把手带你了解 ”图“ 所有知识!(含DFS、BFS)
- 设计模式之单例模式
- AndroidStudio创建JNI 工程与调用
- Java 版植物大战僵尸思路和源码分享!
- 你好MyBatis 入门篇