或使用django-filter过滤MultipleChoices

问题描述 投票:0回答:1

我有一个表单字段,有[1,2,3,4 +]等选项,4 +表示greater than equal,可以选择多个选项。我想用django-filter做过滤器。

我可以为[1,2,3]进行过滤,但我不知道如何使用or进行gte=4

以下的过滤工作[1,2,3]:

class NumberInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
    pass

class PlanFilter(FilterSet):
    obj = django_filters.NumberInFilter(name='object', lookup_expr='in')
    class Meta:
        model = Plan 
        fields= ['object',]

要么

choices= ( 
         (1,1),
         (2,2),
         (3,3),
         )

class PlanFilter(FilterSet):
    obj = django_filters.MultipleChoiceFilter(name='object', choices=choices) 
    ...

那么如何使用gte=4字段过滤多个选项?

django django-filter
1个回答
1
投票

任一选项都只需要对过滤器逻辑进行最小的更改。

Custom .filter() method for NumberInFilter

class NumberInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
    def filter(self, qs, value):
        # CSV-based filters receive a list of values
        if 4 not in value:
            return super(NumberInFilter, self).filter(qs, value)

        value.remove(4)

        # a little bit more verbose, but doesn't require hardcoding the name.
        # eg, `qs.filter(Q(object__in=value) | Q(object__gte=4))`
        q1 = Q(**{'%s__%s' % (self.name, 'in'): value})
        q2 = Q(**{'%s__%s' % (self.name, 'gte'): 4})
        return qs.filter(q1 | q2)

Overriding .get_filter_predicate() in MultipleChoiceFilter

ObjectMultipleChoiceFilter(django_filters.MultipleChoiceFilter):
    def get_filter_predicate(self, value):
        if value == '4':
            return {'%s__gte' % self.name: 4}
        return super(ObjectMultipleChoiceFilter, self).get_filter_predicate(value)
© www.soinside.com 2019 - 2024. All rights reserved.