Skip to content

Commit

Permalink
Add guide/ref docs for request-based filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryan P Kilby committed Oct 29, 2016
1 parent 41f5536 commit 9898ccb
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
17 changes: 17 additions & 0 deletions docs/ref/filters.txt
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,22 @@ Example::
model = Book
fields = ['author']

The ``queryset`` argument also supports callable behavior. If a callable is
passed, it will be invoked with ``Filterset.request`` as its only argument.
This allows you to easily filter by properties on the request object without
having to override the ``FilterSet.__init__``.

.. code-block:: python

def departments(request):
company = request.user.company
return company.department_set.all()

class EmployeeFilter(filters.FilterSet):
department = filters.ModelChoiceFilter(queryset=departments)
...


``ModelMultipleChoiceFilter``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -332,6 +348,7 @@ for ``ManyToManyField`` by default.
As with ``ModelChoiceFilter``, if automatically instantiated,
``ModelMultipleChoiceFilter`` will use the default ``QuerySet`` for the related
field. If manually instantiated you **must** provide the ``queryset`` kwarg.
Like ``ModelChoiceFilter``, the ``queryset`` argument has callable behavior.

To use a custom field name for the lookup, you can use ``to_field_name``::

Expand Down
52 changes: 52 additions & 0 deletions docs/usage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,63 @@ default filters for all the models fields of the same kind using
}


Request-based filtering
~~~~~~~~~~~~~~~~~~~~~~~

The ``FilterSet`` may be initialized with an optional ``request`` argument. If
a request object is passed, then you may access the request during filtering.
This allows you to filter by properties on the request, such as the currently
logged-in user or the ``Accepts-Languages`` header.


Filtering the primary ``.qs``
"""""""""""""""""""""""""""""

To filter the primary queryset by the ``request`` object, simply override the
``FilterSet.qs`` property. For example, you could filter blog articles to only
those that are published and those that are owned by the logged-in user
(presumably the author's draft articles).

.. code-block:: python

class ArticleFilter(django_filters.FilterSet):

class Meta:
model = Article
fields = [...]

@property
def qs(self):
parent = super(ArticleFilter, self).qs
return parent.filter(is_published=True) \
| parent.filter(author=request.user)


Filtering the related queryset for ``ModelChoiceFilter``
"""""""""""""""""""""""""""""""""""""""""""""""""""""""

The ``queryset`` argument for ``ModelChoiceFilter`` and ``ModelMultipleChoiceFilter``
supports callable behavior. If a callable is passed, it will be invoked with the
``request`` as its only argument. This allows you to perform the same kinds of
request-based filtering without resorting to overriding ``FilterSet.__init__``.

.. code-block:: python

def departments(request):
company = request.user.company
return company.department_set.all()

class EmployeeFilter(filters.FilterSet):
department = filters.ModelChoiceFilter(queryset=departments)
...


Customize filtering with ``Filter.method``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

You can control the behavior of a filter by specifying a ``method`` to perform
filtering. View more information in the :ref:`method reference <filter-method>`.
Note that you may access the filterset's properties, such as the ``request``.

.. code-block:: python

Expand Down

0 comments on commit 9898ccb

Please sign in to comment.