diff --git a/docs/guide/migration.txt b/docs/guide/migration.txt index c09e6ac3f..0b6c03773 100644 --- a/docs/guide/migration.txt +++ b/docs/guide/migration.txt @@ -26,6 +26,31 @@ the following to raise the full exception instead: __ https://docs.python.org/3.6/using/cmdline.html#cmdoption-W __ https://docs.python.org/3.6/using/cmdline.html#envvar-PYTHONWARNINGS +---------------- +Migrating to ??? +---------------- + +``Filter.method`` signature changed (`#1150`__) +----------------------------------------------- +__ https://github.com/carltongibson/django-filter/pull/1150 + +The ``Filter.method`` signature is now provided the filter instance (``f``) in +lieu of the filter's ``field_name`` attribute. By providing the filter instance, +methods may now inspect other attributes and respond accordingly (e.g., is the +filter configured to ``exclude`` results or be ``distinct``). The ``field_name`` +should now also be accessed as an attribute on the filter instance. + +.. code-block:: python + + class MyFilterSet(FilterSet): + def old_signature(self, qs, field_name, value): + ... + + def new_signature(self, f, qs, value): + field_name = f.field_name + ... + + ---------------- Migrating to 2.0 ---------------- diff --git a/docs/guide/usage.txt b/docs/guide/usage.txt index 30180a44e..3bb04c060 100644 --- a/docs/guide/usage.txt +++ b/docs/guide/usage.txt @@ -242,10 +242,8 @@ Note that you may access the filterset's properties, such as the ``request``. model = User fields = ['username'] - def my_custom_filter(self, queryset, name, value): - return queryset.filter(**{ - name: value, - }) + def my_custom_filter(self, f, qs, value): + return qs.filter(**{f.field_name: value}) The view diff --git a/docs/ref/filters.txt b/docs/ref/filters.txt index 54d2ce8f0..f6fc10c76 100644 --- a/docs/ref/filters.txt +++ b/docs/ref/filters.txt @@ -56,8 +56,8 @@ on the field ``field_name`` and the parts of the ``lookup_expr`` An optional argument that tells the filter how to handle the queryset. It can accept either a callable or the name of a method on the ``FilterSet``. The -callable receives a ``QuerySet``, the name of the model field to filter on, and -the value to filter with. It should return a filtered ``Queryset``. +callable receives the ``Filter`` instance, a ``QuerySet``, and the value to +filter with. It should return a filtered ``Queryset``. Note that the value is validated by the ``Filter.field``, so raw value transformation and empty value checking should be unnecessary. @@ -68,13 +68,13 @@ transformation and empty value checking should be unnecessary. """Filter for Books by if books are published or not""" published = BooleanFilter(field_name='published_on', method='filter_published') - def filter_published(self, queryset, name, value): + def filter_published(self, f, qs, value): # construct the full lookup expression. - lookup = '__'.join([name, 'isnull']) - return queryset.filter(**{lookup: False}) + lookup = '__'.join([f.field_name, 'isnull']) + return queryset.filter(**{lookup: not value}) # alternatively, it may not be necessary to construct the lookup. - return queryset.filter(published_on__isnull=False) + return queryset.filter(published_on__isnull=not value) class Meta: model = Book @@ -82,9 +82,9 @@ transformation and empty value checking should be unnecessary. # Callables may also be defined out of the class scope. - def filter_not_empty(queryset, name, value): - lookup = '__'.join([name, 'isnull']) - return queryset.filter(**{lookup: False}) + def filter_not_empty(f, qs, value): + lookup = '__'.join([f.field_name, 'isnull']) + return queryset.filter(**{lookup: not value}) class F(FilterSet): """Filter for Books by if books are published or not"""