Skip to content

Commit

Permalink
Add OrderingFilter ref & migration docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan P Kilby committed Sep 4, 2016
1 parent aef0160 commit 352b7d4
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 0 deletions.
35 changes: 35 additions & 0 deletions docs/migration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,38 @@ potential conflicts with declared filter names. This includes:
filter_overrides = {}
strict = STRICTNESS.RAISE_VALIDATION_ERROR
order_by_field = 'order'


FilterSet ordering replaced by OrderingFilter
---------------------------------------------
Details: https://github.com/carltongibson/django-filter/pull/472

The FilterSet ordering options and methods have been deprecated and replaced
by :ref:`OrderingFilter <ordering-filter>`. Deprecated options include:


* ``Meta.order_by``
* ``Meta.order_by_field``

These options retain backwards compatibility with the following caveats:

* ``order_by`` asserts that ``Meta.fields`` is not using the dict syntax. This
previously was undefined behavior, however the migration code is unable to
support it.
* Prior, if no ordering was specified in the request, the FilterSet implicitly
filtered by the first param in the ``order_by`` option. This behavior cannot
be easily emulated but can be fixed by ensuring that the passed in queryset
explicitly calls ``.order_by()``.

.. code-block:: python

filterset = MyFilterSet(queryset=MyModel.objects.order_by('field'))

The following methods are deprecated and will raise an assertion if present
on the FilterSet:

* ``.get_order_by()``
* ``.get_ordering_field()``

To fix this, simply remove the methods from your class. You can subclass
``OrderingFilter`` to migrate any custom logic.
78 changes: 78 additions & 0 deletions docs/ref/filters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -586,3 +586,81 @@ Example::
class Meta:
model = Book
fields = ['published']


.. _ordering-filter:

``OrderingFilter``
~~~~~~~~~~~~~~~~~~

Enable queryset ordering. As an extension of ``ChoiceFilter`` it accepts
two additional arguments that are used to build the ordering choices.

* ``fields`` is a mapping of {model field name: parameter name}. The
parameter names are exposed in the choices and mask/alias the field
names used in the ``order_by()`` call. Similar to field ``choices``,
``fields`` accepts the 'list of two-tuples' syntax that retains order.
``fields`` may also just be an iterable of strings. In this case, the
field names simply double as the exposed parameter names.

* ``field_labels`` is an optional argument that allows you to customize
the display label for the corresponding parameter. It accepts a mapping
of {field name: human readable label}. Keep in mind that the key is the
field name, and not the exposed parameter name.

.. code-block:: python

class UserFilter(FilterSet):
account = CharFilter(name='username')
status = NumberFilter(name='status')

o = OrderingFilter(
# tuple-mapping retains order
fields=(
('username', 'account'),
('first_name', 'first_name'),
('last_name', 'last_name'),
},

# labels do not need to retain order
field_labels={
'username': 'User account',
}
)

class Meta:
model = User
fields = ['first_name', 'last_name']

>>> UserFilter().filter['o'].field.choices
[
('account', 'User account'),
('-account', 'User account (descending)'),
('first_name', 'First name'),
('-first_name', 'First name (descending)'),
('last_name', 'Last name'),
('-last_name', 'Last name (descending)'),
]

Additionally, you can just provide your own ``choices`` if you require
explicit control over the exposed options. For example, when you might
want to disable descending sort options.

.. code-block:: python

class UserFilter(FilterSet):
account = CharFilter(name='username')
status = NumberFilter(name='status')

o = OrderingFilter(
choices=(
('account', 'Account'),
),
fields={
'username': 'account',
},
)

This filter is also CSV-based, and accepts multiple ordering params. The
default select widget does not enable the use of this, but it is useful
for APIs.

0 comments on commit 352b7d4

Please sign in to comment.