I am using Django-filter app to construct search on my website. This is the code:
class PropertyFilter(django_filters.FilterSet):
city = django_filters.ModelMultipleChoiceFilter(queryset=City.objects.all(), widget = CheckboxSelectMultiple)
trade_type = django_filters.ModelMultipleChoiceFilter(queryset=Trade.objects.all(), widget = CheckboxSelectMultiple)
class Meta:
model = Property
fields = ['city', 'trade_type']
The problem is that when user marks two cities, Django-filter only filters objects via last URL parameter (city no. 2 in this casse):
http://example.org/lt/list/city=1&city=2
Models.py
:
class City(models.Model):
name = models.CharField(max_length=250, verbose_name=_('Name'))
Maybe I am doing something wrong ?
You could create a plural version of your query string and accept a list as the filter argument:
http://example.org/lt/list/?cities=1,2
class CustomFilterList(django_filters.Filter):
def filter(self, qs, value):
if value not in (None, ''):
values = [v for v in value.split(',')]
return qs.filter(**{'%s__%s' % (self.name, self.lookup_type): values})
return qs
class PropertyFilter(django_filters.FilterSet):
city = django_filters.ModelMultipleChoiceFilter(queryset=City.objects.all(), widget = CheckboxSelectMultiple)
trade_type = django_filters.ModelMultipleChoiceFilter(queryset=Trade.objects.all(), widget = CheckboxSelectMultiple)
cities = CustomFilterList(name="city", lookup_type="in")
class Meta:
model = Property
fields = ['cities', 'city', 'trade_type']
Check out this answer for filtering a list of values properly:
Possible to do an `in` `lookup_type` through the django-filter URL parser?
You can get it to work with the same URL you were trying. Follow my example. You have to pass the choices that you want to filter with.
The URL that I'm calling:
http://example.org/product-list/gender=1&gender=2
filters.py
GENDER_CHOICES = tuple(
ProductAttributeOptions.objects.filter(group__name='gender').values_list('id', 'option'))
class ProductFilter(django_filters.FilterSet):
gender = django_filters.MultipleChoiceFilter(choices=GENDER_CHOICES,
method='filter_gender')
def filter_gender(self, qs, name, value):
result = qs.filter(Q(attribute_values__attribute__name='gender',
attribute_values__value_option__in=value))
return result
class Meta:
model = Product
fields = ('gender')
Hope this could help. I took inspiration from the official docs.
The best way is to use custom filter from Django filter DOC in my case i used (',') to split the url should look like this:
localhost:8000/?city=1,2,3 (you can use Strings values)
class F(django_filters.FilterSet):
city = CharFilter(method='my_custom_filter')
class Meta:
model = Property
fields = ['city','trade_type']
def my_custom_filter(self, queryset, name, value):
value_list = value.split(u',') #split the values by ,
return queryset.filter(**{
name+"__in": value_list, #add __in to get each value of the list
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With