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)
希望这能让你入门。
我正在使用 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)
希望这能让你入门。