OR 逻辑与 Django-filter

OR logic with Django-filter

我正在使用 Django-filter 来允许用户根据两个字段中的多项选择来过滤数据库。 filterset.py 看起来像这样:

class TapFilter(django_filters.FilterSet):
bar__region = django_filters.MultipleChoiceFilter(choices=CHOICES, label="Regions:", widget=forms.CheckboxSelectMultiple,help_text="")
bar = django_filters.ModelMultipleChoiceFilter(queryset=Bar.objects.all(), label="Bars:", widget=forms.CheckboxSelectMultiple,help_text="")

但是,这起到了两个列表之间的 AND 的作用。我需要 OR 代替。也就是说,我需要显示任何与任一类别中的选择相匹配的内容。

我在使用普通过滤器时看到过类似的问题,但如果可能的话我更愿意继续使用 django-filter。

有问题的网站在这里:http://bestap.pythonanywhere.com/

更新:我已经把它放在我的 filtersets.py 中,但显然我做的事情不正确...

class TapFilter(django_filters.FilterSet):
    bar__region = django_filters.MultipleChoiceFilter(choices=CHOICES, label="Regions:", widget=forms.CheckboxSelectMultiple,help_text="")
    bar = django_filters.ModelMultipleChoiceFilter(queryset=Bar.objects.all(), label="Bars:", widget=forms.CheckboxSelectMultiple,help_text="")
    def qs(self):
        base_qs = Bar.objects.all()
        qs = Bar.objects.none()
        for name, filter_ in six.iteritems(self.filters):
            value = self.form.cleaned_data[name]
            qs = qs | filter_.filter(base_qs, value)
        return qs

这给我错误 'function' object has no attribute 'count'.

您需要在 TapFilter FilterSet 子类上覆盖 qs

base implementation is not that complicated; the essence of it loops over the filters applying them to the queryset

简化版:

for name, filter_ in six.iteritems(self.filters):
    value = self.form.cleaned_data[name]
    qs = filter_.filter(qs, value)

您需要过滤器的查询集的联合,因为 QuerySet implements __or__,您可以获得它,所以(再次简化)您需要类似的东西:

base_qs = Bar.objects.all()
qs = Bar.objects.none()
for name, filter_ in six.iteritems(self.filters):
    value = self.form.cleaned_data[name]
    qs = qs | filter_.filter(base_qs, value)

希望这能让你入门。