Django的generics.ListAPIView按输入日期筛选一周数据及分页实现问题
Django DRF 日期范围过滤+分页实现方案
1. 实现传入日期后查询往后一周数据
你当前使用的原生filterset_fields仅支持简单的条件过滤,无法自动限制一周范围,需自定义过滤类实现需求:
第一步,在你的App目录下新建filters.py文件,代码如下:
from django_filters import rest_framework as filters from datetime import timedelta from .models import MeterLake class MeterLakeFilter(filters.FilterSet): # 绑定createdtimestamp字段的自定义过滤方法 createdtimestamp = filters.DateFilter(field_name='createdtimestamp', method='filter_week_range') class Meta: model = MeterLake fields = { 'siteid': ['exact'], } def filter_week_range(self, queryset, name, value): # 计算用户传入日期往后7天的结束时间 end_date = value + timedelta(days=7) return queryset.filter(**{ f"{name}__gte": value, f"{name}__lte": end_date })
第二步,修改你的views.py,将filterset_fields替换为自定义过滤类:
from rest_framework import generics from django_filters.rest_framework import DjangoFilterBackend from .models import MeterLake from .serializers import MeterLakeSerializer from .filters import MeterLakeFilter class MeterView(generics.ListAPIView): queryset = MeterLake.objects.all() serializer_class = MeterLakeSerializer filter_backends = [DjangoFilterBackend] # 替换为自定义过滤类 filterset_class = MeterLakeFilter
配置完成后用户依旧可以通过url/?createdtimestamp=2024-01-01的形式传参,接口会自动返回该日期到往后7天内的所有匹配数据。
*注意:如果createdtimestamp是DateTimeField类型,请确保传入参数的时区和项目时区保持一致,避免过滤结果出现偏差。
2. 实现分页功能
两种实现方式按需选择:
方式1:全局配置(所有接口统一分页规则)
在项目settings.py中添加DRF全局配置即可:
REST_FRAMEWORK = { # 全局默认分页类 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # 每页默认返回条数 'PAGE_SIZE': 10 }
配置后所有继承DRF通用视图的接口都会自动支持分页,访问时加page参数指定页码即可,比如/?createdtimestamp=2024-01-01&page=2。
方式2:视图独立配置(仅当前接口生效,灵活性更高)
如果只需要给MeterView单独配置分页规则,或者需要自定义分页参数,可以单独定义分页类:
首先在views.py中导入并自定义分页类:
from rest_framework.pagination import PageNumberPagination # 自定义分页类 class CustomMeterPagination(PageNumberPagination): # 每页默认返回条数 page_size = 10 # 页码参数名,比如page=1就是访问第一页 page_query_param = 'page' # 支持用户自定义每页条数的参数名,比如page_size=20就是每页返回20条 page_size_query_param = 'page_size' # 每页最大条数限制,防止用户请求过大导致接口超时 max_page_size = 100
然后给MeterView关联分页类即可:
class MeterView(generics.ListAPIView): queryset = MeterLake.objects.all() serializer_class = MeterLakeSerializer filter_backends = [DjangoFilterBackend] filterset_class = MeterLakeFilter # 关联自定义分页类 pagination_class = CustomMeterPagination
接口调用示例
# 查询siteid为2,日期2024-05-01往后一周的数据,第1页,每页返回15条 https://your-api-domain/meter-endpoint/?siteid=2&createdtimestamp=2024-05-01&page=1&page_size=15
返回结果会自动带上总条数、上一页/下一页链接、当前页数据等标准分页字段。
内容的提问来源于stack exchange,提问作者Robbie Eisenrich
相关产品推荐
相关产品推荐

