Django过滤器:建议改进动态过滤逻辑

时间:2018-10-20 10:25:48

标签: python django django-rest-framework q django-filter

我正在根据前端用户选择的多种搜索条件对数据集进行过滤。这里有一些注意事项:

  • 所有过滤条件均为非强制性条件。用户可以选择/输入值或将其留为空白。后端必须找出一种检查NULL的方法。
  • 下拉列表是多选的,因此过滤器表单数据可以具有多个ID列表。 (很多IN查询)
  • 还有DATE(从/到)相关字段,也可以将其留空。因此,代码必须处理以下情况:日期范围过滤|日期> DDMMYYYY |日期

这是表格的外观: my form

这是我目前的方法:

class BookingExportFilterBackend(generic_filters.BaseFilterBackend):
    def filter_queryset(self, request, queryset, view):
        predicate = request.data

        if all(dt in predicate for dt in ('from_date', 'to_date')):
            queryset = queryset.filter(date__range=(predicate['from_date'], predicate['to_date']))

        if 'from_date' in predicate and 'to_date' not in predicate:
            queryset = queryset.filter(date__gte=predicate['from_date'])

        if 'to_date' in predicate and 'from_date' not in predicate:
            queryset = queryset.filter(date__lte=predicate['to_date'])

        if 'state' in predicate:
            queryset = queryset.filter(state__in=predicate['state'])

        if 'clients' in predicate:
            queryset = queryset.filter(client__in=predicate['clients'])

        if 'camera_operators' in predicate:
            queryset = queryset.filter(camera_operator__uuid__in=predicate['camera_operators'])

        return queryset

我认为它可以改进,尤其是日期部分。我也正在使用Q库,但是对于Django我还是很陌生。 (PS:我来自Java / Spring / Hibernate背景)。

请帮助改进代码。

1 个答案:

答案 0 :(得分:1)

您应尝试使用django-filters库进行过滤。它非常易于使用,并提供了一系列过滤选项。

对于您的情况,您可以从以下内容开始: 注意:请不要使用date作为字段/变量名称,在下面的示例中,我已经用booking_date替换了。

class BookingFilter(django_filters.FilterSet):
    from_date = django_filters.NumberFilter(field_name='booking_date', lookup_expr='gt')
    to_date = django_filters.NumberFilter(field_name='booking_date', lookup_expr='lt')

    status = django_filters.CharFilter(name="status", lookup_type="contains"

    class Meta:
        model = Booking # replace with your appropriate Model