【问题标题】:django, limit generics.ListAPIView by week of user entered filterset_fielddjango,按用户输入 filterset_field 的周数限制 generics.ListAPIView
【发布时间】:2021-11-19 19:35:38
【问题描述】:

刚接触 django 并开始使用 api。我希望我的视图接受一个过滤器集字段,然后在一周内返回大于该字段的数据。我目前设置的视图是

views.py

class MeterView(generics.ListAPIView):

    queryset = MeterLake.objects.all()
    serializer_class = MeterLakeSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = {'siteid' : ['exact'], 
                        'createdtimestamp' : ['gte'],
                        
                        }

然后用户将输入 url/?createdtimestamp=date 然后我想获取用户输入的日期并返回该日期超过一周的信息。

理想情况下,我想为此使用分页,但我不确定如何 非常感谢任何帮助!

【问题讨论】:

    标签: python django-views django-pagination


    【解决方案1】:

    您可以通过提供要使用的自定义 filterset_class 来自定义 createdtimestamp 过滤器字段的使用方式,而不是您当前使用的速记方式。

    例如,通过提供过滤器的方法,您可以调整用于查找的值。

    
    from django_filters import rest_framework as filters
    from datetime import datetime, timedelta
    
    class MeterLakeFilter(filters.FilterSet):
        createdtimestamp = filters.BooleanFilter(
            field_name='createdtimestamp', method='filter_a_week_from_date'
        )
    
        class Meta:
            model = MeterLake
            fields = ['createdtimestamp', 'siteid']
    
        def filter_a_week_from_date(self, queryset, name, value):
            lookup = f'{name}__gte'
            dateformat = '%Y-%m-%d' # replace with expected value format.
            # value may be serialized already, thus not needing to be parsed here.
            value = datetime.strptime(value, dateformat) + timedelta(days=7)
            return queryset.filter(**{lookup: value})
    
    
    class MeterView(generics.ListAPIView):
        queryset = MeterLake.objects.all()
        serializer_class = MeterLakeSerializer
        filter_backends = [DjangoFilterBackend]
        filterset_class = MeterLakeFilter
    

    【讨论】:

    • 谢谢!这在按 siteid 过滤时效果很好,但在按日期过滤时却很困难。我认为这个问题可能与我的日期时间值有关。检查价值的最佳方法是什么?通常我会打印出来,但我无法访问变量。
    【解决方案2】:

    使用 Oluwafemi Sule 的回答,我能够调整自定义过滤器和通用视图,以便按 siteid 和输入的时间戳一周后进行搜索。如果没有指定时间戳,我还添加了一些功能以将时间范围限制为从今天开始的一周。

    class MeterLakeFilter(filters.FilterSet):
        siteid = filters.CharFilter(field_name='siteid')
        createdtimestamp = DateTimeFilter(field_name = 'createdtimestamp', method = 'filter_a_week_from_date')
        
        class Meta:
            model = MeterLake
            fields = ['siteid', 'createdtimestamp']
    
        def filter_a_week_from_date(self,queryset, name, value):
            
            if self.request.query_params.get('createdtimestamp', 'None') == None:
                lookup = f'{name}__gte'
                value = datetime.now() + timedelta(days=7)
                return queryset.filter(**{lookup: value})
            
            else:
                value2 = value + timedelta(days=7)
                return queryset.filter(createdtimestamp__lte = value2, createdtimestamp__gte = value)
    
    class MeterView(generics.ListAPIView):
        
        queryset = MeterLake.objects.all()
        serializer_class = MeterLakeSerializer
        filter_backends = [DjangoFilterBackend,OrderingFilter]
        filterset_class = MeterLakeFilter
        ordering_fields = ['siteid', 'createdtimestamp']
        ordering = ['siteid', 'createdtimestamp']
    
        def get_queryset(self):
            if self.request.query_params.get('createdtimestamp', None) == None:
                start_date = datetime.utcnow().replace(tzinfo=pytz.utc)
                end_date = start_date - timedelta(days=7)
                queryset = MeterLake.objects.filter(createdtimestamp__gte = end_date).order_by('createdtimestamp')
                
                return queryset
            else:
                
                pass
        
    

    【讨论】:

      猜你喜欢
      • 2012-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      相关资源
      最近更新 更多