views:

95

answers:

2

I've got a list of objects (properties for rent, in this case) that I am listing, the list needs to be filterable by a handful of criteria (max price, area, n_bedrooms ...) and I figured I could do it like this:

(r'^price:(?P<price_min>\d+)?-(?P<price_max>\d+)?/$', property_list)

This works, and allows urls like price:300-600/ to do the sensible thing.

However, it becomes unwieldy when there's around half a dozen attributes one could be filtering by, and ideally I would like clean urls (i.e. not including attributes for which we're not currently filtering in the url)

Is there a "standard" way to handle this in Django?

+4  A: 

The right way to do this in django is Alex Gaynor, err django-filter by Alex Gaynor

It lets you get the filter parameters as http get and filters your queryset on those constraints.

From the docs:

import django_filters

class ProductFilterSet(django_filters.FilterSet):
    class Meta:
        model = Product
        fields = ['name', 'price', 'manufacturer']

And then in your view you could do::

def product_list(request):
    filterset = ProductFilterSet(request.GET or None)
    return render_to_response('product/product_list.html',
        {'filterset': filterset})
Lakshman Prasad
This takes care of the filtering, but (doesn't!) handle the messy part I mentioned above, the keeping-urls-clean by using get-parameters, which means you *do* get the long-and-messy-urls. Or maybe I'm overlooking something ?
Agrajag
+2  A: 

In case you don't need to reverse these urls you may use optional groups:

urls.py:

#the regex might need some work, it's just a concept
(r'^(price(/(?P<price_min>\d+))?(/to/(?P<price_max>\d+))?/$ 

views.py:

def view(request,min_price=None,max_price=None):
    ...

(django_filters is very nice though)

Till Backhaus
Yeah. I considered that, was just wondering if there's a better way. I'll ponder it, thank you for your time !
Agrajag