weixin_46253891 2024-07-11 14:35 采纳率: 58.3%
浏览 5

django-filter根据年月筛选对应月份信息

我像进行年月筛选, 选择年月的话,就可以筛选出这个年月的所有记录,例如我只需要输入2024-06就可以显示出2024-06-01到2024-06-30的范围
我只需要在url上加上 ?month=2024-06 就行

我的filter.py

class ConsumeDetailsFilter(FilterSet):
    # date = filters.DateFilter(field_name='date')
    start_date = filters.DateFilter(field_name='date', lookup_expr='gte', label='Start Date')
    end_date = filters.DateFilter(field_name='date', lookup_expr='lte', label='End Date')
    category = filters.CharFilter(field_name='category', lookup_expr='icontains')
    subcategory = filters.CharFilter(field_name='subcategory', lookup_expr='icontains')
    vendor = filters.CharFilter(field_name='vendor', lookup_expr='icontains')
    item = filters.CharFilter(field_name='item', lookup_expr='icontains')

    class Meta:
        model = ConsumeDetails
        fields = ['start_date','end_date','category', 'subcategory']

我的 views.py

class ConsumeDetailsViewSet(ModelViewSet):
    queryset = ConsumeDetails.objects.all()
    serializer_class = ConsumeDetailsSerializer

    # filter_backends = (DjangoFilterBackend,) #在settings.py里面做了全局添加。这里可以不需要
    # filter_class = ConsumeDetailsFilter  # 这个方法在django-filter 21.1 以上版本中已经废弃,视频教程是这个方法。
    # filterset_fields = ['consumepurpose','consumetype','category','subcategory']
    filterset_class = ConsumeDetailsFilter
    filterset_fields  = ['start_date', 'end_date'] #'consumepurpose', 'consumetype', 'category', 'subcategory'

    pagination_class = MyPageNumberPagination

    # filter_backends = (SearchFilter,) #在settings.py里面做了全局添加。这里可以不需要
    search_fields = ['category','subcategory','vendor','item']
  • 写回答

4条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-07-11 14:35
    关注

    引自免费微信小程序:皆我百晓生

    为了实现基于年月的筛选功能,您可以根据以下的思路对现有的 FilterSet 进行调整。首先,您需要定义一个单独的过滤参数来处理年月筛选,这个参数可以根据传入的 URL 参数来判断是否需要过滤数据。具体的做法是在您的 FilterSet 中增加一个单独的日期过滤字段。您可以将您的代码做如下的调整:

    修改filter.py:

    import django_filters
    from django.utils import timezone
    from datetime import timedelta
    
    class ConsumeDetailsFilter(django_filters.FilterSet):
        # 定义年月筛选字段,这里假设日期字段名为 'date'
        year_month = django_filters.CharFilter(method='filter_by_year_month')
        start_date = django_filters.DateFilter(field_name='date', lookup_expr='gte', label='开始日期')
        end_date = django_filters.DateFilter(field_name='date', lookup_expr='lte', label='结束日期')
        # 其他已有的过滤字段保持不变...
        
        def filter_by_year_month(self, queryset, name, value):
            if value:  # 如果传入了年月值,则进行筛选操作
                year, month = map(int, value.split('-'))  # 解析年月值,例如:解析 '2024-06' 到 (2024, 6)
                # 获取指定年月的起始和结束日期(可选,根据实际需求调整)
                start_of_month = timezone.datetime(year=year, month=month, day=1)  # 开始日期为该月第一天
                end_of_month = timezone.datetime(year=year, month=month, day=1) + timedelta(days=31) - timedelta(days=timezone.daylight_saving())  # 结束日期为该月最后一天(考虑时区差异)
                return queryset.filter(date__gte=start_of_month, date__lte=end_of_month)  # 使用filter方法筛选出指定年月的数据记录
            return queryset  # 如果未传入值,则返回原始查询集(不进行筛选)
        
        class Meta:
            model = ConsumeDetails  # 设置关联模型类(根据您的模型名称修改)
            fields = ['year_month', 'start_date', 'end_date']  # 设置前端展示的过滤字段列表(根据实际情况调整)
    

    在上述代码中,我们添加了一个名为 year_monthCharFilter,并且创建了一个与之对应的方法 filter_by_year_month 来处理年月筛选逻辑。这个方法会根据传入的年月值进行过滤,并返回符合这个条件的记录集。当您通过URL传递参数时,只需要按照指定的格式(如 ?year_month=2024-06)即可进行筛选。对于年份和月份的计算,您可以根据实际情况调整日期范围和时区设置。注意这个示例假设您的日期字段是标准的Django日期字段。如果您的日期字段有其他格式或处理方式,请相应地调整代码。同时确保您的Django版本和django-filter版本兼容该实现。如果您的服务器位于不同地区或使用特殊时区设置,确保考虑了相应的时区因素以正确计算日期的边界值。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 7月11日

悬赏问题

  • ¥15 16进制修改视频的元数据
  • ¥15 思科模拟器Router c3600 NM-4E
  • ¥15 岛津txt格式文件转nirs格式
  • ¥15 石墨烯磁表面等离子体
  • ¥15 angular 项目无法启动
  • ¥15 安装wampserver,图标绿色,但是无法进入软件
  • ¥15 C++ MFC 标准库 加密解密解惑
  • ¥15 两条数据合并成一条数据
  • ¥15 Ubuntu虚拟机设置
  • ¥15 comsol三维模型中磁场为什么没有“速度(洛伦兹项)”这一选项