Commit ff1234b7 by Tom Christie

Updated filteing docs.

parent ad9c5d2f
...@@ -30,7 +30,7 @@ For example: ...@@ -30,7 +30,7 @@ For example:
for the currently authenticated user. for the currently authenticated user.
""" """
user = self.request.user user = self.request.user
return Purchase.objects.filter(purchaser=user) return Purchase.objects.filter(purchaser=user)
## Filtering against the URL ## Filtering against the URL
...@@ -96,27 +96,76 @@ You must also set the filter backend to `DjangoFilterBackend` in your settings: ...@@ -96,27 +96,76 @@ You must also set the filter backend to `DjangoFilterBackend` in your settings:
**Note**: The currently supported version of `django-filter` is the `master` branch. A PyPI release is expected to be coming soon. **Note**: The currently supported version of `django-filter` is the `master` branch. A PyPI release is expected to be coming soon.
## Specifying filter fields
If all you need is simple equality-based filtering, you can set a `filter_fields` attribute on the view, listing the set of fields you wish to filter against.
class ProductList(generics.ListAPIView):
model = Product
serializer_class = ProductSerializer
filter_fields = ('category', 'in_stock')
This will automatically create a `FilterSet` class for the given fields, and will allow you to make requests such as:
http://example.com/api/products?category=clothing&in_stock=True
## Specifying a FilterSet ## Specifying a FilterSet
**TODO**: Document setting `.filter_class` on the view. For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view. For example:
**TODO**: Note support for `lookup_type`, double underscore relationship spanning, and ordering. class ProductFilter(django_filters.FilterSet):
min_price = django_filters.NumberFilter(lookup_type='gte')
max_price = django_filters.NumberFilter(lookup_type='lte')
class Meta:
model = Product
fields = ['category', 'in_stock', 'min_price', 'max_price']
## Specifying filter fields class ProductList(generics.ListAPIView):
model = Product
serializer_class = ProductSerializer
filter_class = ProductFilter
**TODO**: Document setting `.filter_fields` on the view. Which will allow you to make requests such as:
**TODO**: Note that overiding `get_queryset()` can be used together with generic filtering http://example.com/api/products?category=clothing&max_price=10.00
For more details on using filter sets see the [django-filter documentation][django-filter-docs].
---
**Hints & Tips**
* By default filtering is not enabled. If you want to use `DjangoFilterBackend` remember to make sure it is installed by using the `'FILTER_BACKEND'` setting.
* When using boolean fields, you should use the values `True` and `False` in the URL query parameters, rather than `0`, `1`, `true` or `false`. (The allowed boolean values are currently hardwired in Django's [NullBooleanSelect implementation][nullbooleanselect].)
* `django-filter` supports filtering across relationships, using Django's double-underscore syntax.
---
## Overriding the intial queryset
Note that you can use both an overridden `.get_queryset()` and generic filtering together, and everything will work as expected. For example, if `Product` had a many-to-many relationship with `User`, named `purchase`, you might want to write a view like this:
class PurchasedProductsList(generics.ListAPIView):
"""
Return a list of all the products that the authenticated
user has ever purchased, with optional filtering.
"""
model = Product
serializer_class = ProductSerializer
filter_class = ProductFilter
def get_queryset(self):
user = self.request.user
return user.purchase_set.all()
--- ---
# Custom generic filtering # Custom generic filtering
You can also provide your own generic filtering backend, or write an installable app for other developers to use. You can also provide your own generic filtering backend, or write an installable app for other developers to use.
To do so overide `BaseFilterBackend`, and override the `.filter_queryset(self, request, queryset, view)` method. To do so override `BaseFilterBackend`, and override the `.filter_queryset(self, request, queryset, view)` method.
To install the filter, set the `'FILTER_BACKEND'` key in your `'REST_FRAMEWORK'` setting, using the dotted import path of the filter backend class. To install the filter backend, set the `'FILTER_BACKEND'` key in your `'REST_FRAMEWORK'` setting, using the dotted import path of the filter backend class.
For example: For example:
...@@ -125,4 +174,6 @@ For example: ...@@ -125,4 +174,6 @@ For example:
} }
[cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters [cite]: https://docs.djangoproject.com/en/dev/topics/db/queries/#retrieving-specific-objects-with-filters
[django-filter]: https://github.com/alex/django-filter [django-filter]: https://github.com/alex/django-filter
\ No newline at end of file [django-filter-docs]: https://django-filter.readthedocs.org/en/latest/index.html
[nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py
\ No newline at end of file
...@@ -34,6 +34,7 @@ The following packages are optional: ...@@ -34,6 +34,7 @@ The following packages are optional:
* [Markdown][markdown] (2.1.0+) - Markdown support for the self describing API. * [Markdown][markdown] (2.1.0+) - Markdown support for the self describing API.
* [PyYAML][yaml] (3.10+) - YAML content-type support. * [PyYAML][yaml] (3.10+) - YAML content-type support.
* [django-filter][django-filter] (master) - Filtering support.
## Installation ## Installation
...@@ -163,6 +164,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ...@@ -163,6 +164,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[urlobject]: https://github.com/zacharyvoase/urlobject [urlobject]: https://github.com/zacharyvoase/urlobject
[markdown]: http://pypi.python.org/pypi/Markdown/ [markdown]: http://pypi.python.org/pypi/Markdown/
[yaml]: http://pypi.python.org/pypi/PyYAML [yaml]: http://pypi.python.org/pypi/PyYAML
[django-filter]: https://github.com/alex/django-filter
[0.4]: https://github.com/tomchristie/django-rest-framework/tree/0.4.X [0.4]: https://github.com/tomchristie/django-rest-framework/tree/0.4.X
[image]: img/quickstart.png [image]: img/quickstart.png
[sandbox]: http://restframework.herokuapp.com/ [sandbox]: http://restframework.herokuapp.com/
......
from rest_framework.compat import django_filters from rest_framework.compat import django_filters
FilterSet = django_filters and django_filters.FilterSet or None
class BaseFilterBackend(object): class BaseFilterBackend(object):
""" """
...@@ -17,7 +19,7 @@ class DjangoFilterBackend(BaseFilterBackend): ...@@ -17,7 +19,7 @@ class DjangoFilterBackend(BaseFilterBackend):
""" """
A filter backend that uses django-filter. A filter backend that uses django-filter.
""" """
default_filter_set = django_filters.FilterSet default_filter_set = FilterSet
def __init__(self): def __init__(self):
assert django_filters, 'Using DjangoFilterBackend, but django-filter is not installed' assert django_filters, 'Using DjangoFilterBackend, but django-filter is not installed'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment