在django-filters中使用__in进行自定义查询

时间:2018-11-06 22:12:40

标签: django-filter

我正在使用Django过滤器1.1.0。我需要编写一个使用自定义查询的过滤器,但在其中可以选择使用__in后缀。

这是我的解决方案,但是我不禁希望有一种更简洁的方式来进行此操作,类似于指定id的方式-也许对bar和'exact'使用单一方法或'__in'作为查找参数传递。

class FooFilter(filters.FilterSet):

    bar_id = filters.CharFilter(method='filter_bar_id', label='Bar')
    bar_id__in = filters.CharFilter(method='filter_bar_id__in', label='Bar In')


    def filter_bar_id(self, queryset, name, value):
        return queryset.filter(
            Q(abc__xyz__bar=value) |
            Q(def__xyz__bar=value)).distinct()

    def filter_bar_id__in(self, queryset, name, value):
        bars = value.split(',')
        return queryset.filter(
            Q(abc__xyz__bar__in=bars) |
            Q(def__xyz__bar__in=bars)).distinct()

    class Meta:
        model = Foo
        fields = {
            'id': ['exact', 'in'],
            'bar_id': ['exact'],
            'bar_id__in': ['exact'],
        }

django-filters是否有一种更本地化的方法?还是这几乎是完成此任务的方法?

还有另一个使用bar_id=来同时允许?bar_id=1?bar_id=1,2,3,4的stackoverflow问题。为了与我的其他django过滤器(例如?id?id__in)保持一致,我对此没有兴趣。

1 个答案:

答案 0 :(得分:0)

您可以利用class CharListFilter(filters.BaseInFilter, filters.CharFilter): pass class FooFilter(filters.FilterSet): bar_id = filters.CharFilter(method='filter_bar_id', label='Bar') bar_id__in = filters.CharListFilter(method='filter_bar_id', label='Bar In') def filter_bar_id(self, queryset, name, value): if isinstance(value, list): return queryset.filter( Q(abc__xyz__bar__in=value) | Q(def__xyz__bar__in=value)).distinct() return queryset.filter( Q(abc__xyz__bar=value) | Q(def__xyz__bar=value)).distinct() 的验证逻辑,该逻辑会将逗号分隔的输入值转换为值列表。从那里,您的自定义过滤器方法可以根据值的类型进行切换。

也就是说,我认为这种解决方案不一定比您目前拥有的解决方案优越。而且,这通常不适用于其他查找表达式。在这种情况下,您只能碰巧打开文字。

void test_func(std::optional<std::vector<int>&> vec)