Django filter url parameters
I am using a Django-filter application to create a search engine on my site. 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 a user marks two cities, the Django filter filters objects only through the last URL parameter (city # 2 in this checkout):
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 can create a multiple version of the query string and take a list as a 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 the list of values correctly:
Is it possible to execute `in`` lookup_type` through the django-filter parser?
You can make it work with the same url you tried. Follow my lead. You must go through the selection you want to filter.
The url I am 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 helps. I took inspiration from the official docs .