Skip to content

Commit

Permalink
Merge pull request carltongibson#190 from carltongibson/159
Browse files Browse the repository at this point in the history
Allow Min/Max-Only use of RangeFilter
  • Loading branch information
Carlton Gibson committed Nov 26, 2014
2 parents 2145283 + 15b2c8d commit c54aaa0
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
6 changes: 6 additions & 0 deletions django_filters/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,14 @@ class RangeFilter(Filter):

def filter(self, qs, value):
if value:
if value.start and value.stop:
lookup = '%s__range' % self.name
return qs.filter(**{lookup: (value.start, value.stop)})
else:
if value.start:
qs = qs.filter(**{'%s__gte'%self.name:value.start})
if value.stop:
qs = qs.filter(**{'%s__lte'%self.name:value.stop})
return qs


Expand Down
29 changes: 24 additions & 5 deletions docs/ref/filters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,18 @@ This filter matches an item of any type by choices, used with any field that
has ``choices``.

``TypedChoiceFilter``
~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~

The same as ``ChoiceFilter`` with the added possibility to convert value to
match against. This could be done by using `coerce` parameter.
An example use-case is limiting boolean choices to match against so only
some predefined strings could be used as input of a boolean filter:
some predefined strings could be used as input of a boolean filter::

.. sourcecode:: python
import django_filters
from distutils.util import strtobool

BOOLEAN_CHOICES = (('false', 'False'), ('true', 'True'),)

class YourFilterSet(django_filters.FilterSet):
...
flag = django_filters.TypedChoiceFilter(choices=BOOLEAN_CHOICES,
Expand Down Expand Up @@ -96,7 +95,27 @@ and ``DecimalField`` by default.
``RangeFilter``
~~~~~~~~~~~~~~~

Filters where a value is between two numerical values.
Filters where a value is between two numerical values, or greater than a minimum or less than a maximum where only one limit value is provided. ::

class F(FilterSet):
"""Filter for Books by Price"""
price = RangeFilter()

class Meta:
model = Book
fields = ['price']

qs = Book.objects.all().order_by('title')

# Range: Books between 5€ and 15€
f = F({'price_0': '5', 'price_1': '15'}, queryset=qs)

# Min-Only: Books costing more the 11€
f = F({'price_0': '11'}, queryset=qs)

# Max-Only: Books costing less than 19€
f = F({'price_1': '19'}, queryset=qs)


``DateRangeFilter``
~~~~~~~~~~~~~~~~~~~
Expand Down
10 changes: 10 additions & 0 deletions tests/test_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,16 @@ class Meta:
['Ender\'s Game', 'Rainbow Six'],
lambda o: o.title)

f = F({'price_0': '11'}, queryset=qs)
self.assertQuerysetEqual(f.qs,
['Rainbow Six', 'Snowcrash'],
lambda o: o.title)
f = F({'price_1': '19'}, queryset=qs)
self.assertQuerysetEqual(f.qs,
['Ender\'s Game', 'Rainbow Six'],
lambda o: o.title)



@unittest.skip('date-range is funky')
class DateRangeFilterTests(TestCase):
Expand Down

0 comments on commit c54aaa0

Please sign in to comment.