Skip to content

Commit

Permalink
Merge pull request carltongibson#106 from timheap/develop
Browse files Browse the repository at this point in the history
Add `FilterSet.get_order()` method for very custom ordering
  • Loading branch information
apollo13 committed Aug 10, 2013
2 parents 36180d5 + 7d474fc commit 6e28c45
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 1 deletion.
5 changes: 4 additions & 1 deletion django_filters/filterset.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ def qs(self):
ordered_value = self.form.fields[self.order_by_field].choices[0][0]

if ordered_value:
qs = qs.order_by(ordered_value)
qs = qs.order_by(*self.get_order_by(ordered_value))

self._qs = qs

Expand Down Expand Up @@ -342,6 +342,9 @@ def ordering_field(self):
self._ordering_field = self.get_ordering_field()
return self._ordering_field

def get_order_by(self, order_choice):
return [order_choice]

@classmethod
def filter_for_field(cls, f, name):
filter_for_field = dict(FILTER_FOR_DBFIELD_DEFAULTS)
Expand Down
18 changes: 18 additions & 0 deletions docs/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,24 @@ If you want to use a custom widget, or in any other way override the ordering
field you can override the ``get_ordering_field()`` method on a ``FilterSet``.
This method just needs to return a Form Field.

Ordering on multiple fields, or other complex orderings can be achieved by
overriding the ``Filterset.get_order_by()`` method. This is passed the selected
``order_by`` value, and is expected to return an iterable of values to pass to
``QuerySet.order_by``. For example, to sort a ``User`` table by last name, then
first name::

class UserFilter(django_filters.FilterSet):
class Meta:
order_by = (
('username', 'Username'),
('last_name', 'Last Name')
)

def get_order_by(self, order_value):
if order_value == 'last_name':
return ['last_name', 'first_name']
return super(UserFilter, self).get_order_by(order_value)

Generic View
------------

Expand Down
21 changes: 21 additions & 0 deletions tests/test_filterset.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,3 +533,24 @@ class Meta:
self.assertQuerysetEqual(
f.qs, ['carl', 'alex', 'jacob', 'aaron'], lambda o: o.username)

def test_custom_ordering(self):

class F(FilterSet):
debug = True
class Meta:
model = User
fields = ['username', 'status']
order_by = ['username', 'status']

def get_order_by(self, order_choice):
if order_choice == 'status':
return ['status', 'username']
return super(F, self).get_order_by(order_choice)

f = F({'o': 'username'}, queryset=self.qs)
self.assertQuerysetEqual(
f.qs, ['aaron', 'alex', 'carl', 'jacob'], lambda o: o.username)

f = F({'o': 'status'}, queryset=self.qs)
self.assertQuerysetEqual(
f.qs, ['carl', 'alex', 'aaron', 'jacob'], lambda o: o.username)

0 comments on commit 6e28c45

Please sign in to comment.