Updated filteing docs.

This commit is contained in:
Tom Christie 2012-11-09 13:05:36 +00:00
parent ad9c5d2ffa
commit ff1234b711
3 changed files with 68 additions and 13 deletions

View File

@ -30,7 +30,7 @@ For example:
for the currently authenticated user.
"""
user = self.request.user
return Purchase.objects.filter(purchaser=user)
return Purchase.objects.filter(purchaser=user)
## Filtering against the URL
@ -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.
## Specifying a FilterSet
**TODO**: Document setting `.filter_class` on the view.
**TODO**: Note support for `lookup_type`, double underscore relationship spanning, and ordering.
## Specifying filter fields
**TODO**: Document setting `.filter_fields` on the view.
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.
**TODO**: Note that overiding `get_queryset()` can be used together with generic filtering
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
For more advanced filtering requirements you can specify a `FilterSet` class that should be used by the view. For example:
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']
class ProductList(generics.ListAPIView):
model = Product
serializer_class = ProductSerializer
filter_class = ProductFilter
Which will allow you to make requests such as:
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
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:
@ -125,4 +174,6 @@ For example:
}
[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
[django-filter-docs]: https://django-filter.readthedocs.org/en/latest/index.html
[nullbooleanselect]: https://github.com/django/django/blob/master/django/forms/widgets.py

View File

@ -34,6 +34,7 @@ The following packages are optional:
* [Markdown][markdown] (2.1.0+) - Markdown support for the self describing API.
* [PyYAML][yaml] (3.10+) - YAML content-type support.
* [django-filter][django-filter] (master) - Filtering support.
## Installation
@ -163,6 +164,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[urlobject]: https://github.com/zacharyvoase/urlobject
[markdown]: http://pypi.python.org/pypi/Markdown/
[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
[image]: img/quickstart.png
[sandbox]: http://restframework.herokuapp.com/

View File

@ -1,5 +1,7 @@
from rest_framework.compat import django_filters
FilterSet = django_filters and django_filters.FilterSet or None
class BaseFilterBackend(object):
"""
@ -17,7 +19,7 @@ class DjangoFilterBackend(BaseFilterBackend):
"""
A filter backend that uses django-filter.
"""
default_filter_set = django_filters.FilterSet
default_filter_set = FilterSet
def __init__(self):
assert django_filters, 'Using DjangoFilterBackend, but django-filter is not installed'