url_filter.filters module

class url_filter.filters.BaseFilter(source=None, *args, **kwargs)[source]

Bases: object

Base class to be used for defining both filters and filtersets.

This class implements the bare-minimum functions which are used across both filters and filtersets however all other functionality must be implemented in subclasses. Additionally by using a single base class, both filters and filtersets inherit from the same base class hence instance checks can be easily done by filteset’s metaclass in order to find all declared filters defined in it.

Parameters:source (str) – Name of the attribute for which which filter applies to within the model of the queryset to be filtered as given to the FilterSet.

FilterSet – Parent FilterSet to which this filter is bound to


str – Name of the field as it is defined in parent FilterSet


bool – If this filter has been bound to a parent yet

bind(name, parent)[source]

Bind the filter to the filterset.

This method should be used by the parent FilterSet since it allows to specify the parent and name of each filter within the filterset.


List of all components (source names) of all parent filtersets.


Get the representation of the filter or its subclasses.

Subclasses must overwrite this method.


This class should return unicode text data

Parameters:prefix (str) – All nested filtersets provide useful representation of the complete filterset including all descendants however in that case descendants need to be indented in order for the representation to get structure. This parameter is used to do just that. It specifies the prefix the representation must use before returning any of its representations.

This gets the root filterset.


Source field/attribute in queryset model to be used for filtering.

This property is helpful when source parameter is not provided when instantiating BaseFilter or its subclasses since it will use the filter name as it is defined in the FilterSet. For example:

>>> from .filtersets import FilterSet
>>> class MyFilterSet(FilterSet):
...     foo = Filter(form_field=forms.CharField())
...     bar = Filter(source='stuff', form_field=forms.CharField())
>>> fs = MyFilterSet()
>>> print(fs.filters['foo'].source)
>>> print(fs.filters['bar'].source)
class url_filter.filters.CallableFilter(form_field=None, *args, **kwargs)[source]

Bases: url_filter.filters.Filter

Custom filter class meant to be subclassed in order to add support for custom lookups via custom callables

The goal of this filter is to provide:

  • support for custom callbacks (or overwrite existing ones)
  • support different filtering backends

Custom callable functions for lookups and different backends are defined via class methods by using the following method name pattern:


Obviously multiple methods can be used to implement functionality for multiple lookups and/or backends. This makes callable filters pretty flexible and ideal for implementing custom reusable filtering filters which follow DRY.


>>> from django.http import QueryDict
>>> from .filtersets import FilterSet

>>> class MyCallableFilter(CallableFilter):
...     @form_field_for_filter(forms.CharField())
...     def filter_foo_for_django(self, queryset, spec):
...         f = queryset.filter if not spec.is_negated else queryset.exclude
...         return f(foo=spec.value)
...     def filter_foo_for_sqlalchemy(self, queryset, spec):
...         op = operator.eq if not spec.is_negated else operator.ne
...         return queryset.filter(op(Foo.foo, spec.value))

>>> class MyFilterSet(FilterSet):
...     field = MyCallableFilter()

>>> f = MyFilterSet(data=QueryDict('field__foo=bar'), queryset=[])


Unlike base class Filter this filter makes form_field parameter optional. Please note however that when form_field parameter is not provided, all custom filter callables should define their own appropriate form fields by using form_field_for_filter().


Get the form field for a particular lookup.

This method attempts to return form field for custom callables as set by form_field_for_filter(). When either custom lookup is not set or its form field is not set, super implementation is used to get the form field. If form field at that point is not found, this method raises AssertionError. That can only happen when form_field parameter is not provided during initialization.


Get the FilterSpec for the given LookupConfig with appropriately set FilterSpec.filter_callable when the lookup is a custom lookup


Get all supported lookups for the filter

This property is identical to the super implementation except it also finds all custom lookups from the class methods and adds them to the set of supported lookups as returned by the super implementation.

class url_filter.filters.Filter(form_field, lookups=None, default_lookup=u'exact', is_default=False, no_lookup=False, *args, **kwargs)[source]

Bases: url_filter.filters.BaseFilter

Class which job is to convert leaf LookupConfig to FilterSpec

Each filter by itself is meant to be used a “filter” (field) in the FilterSet.


>>> from .filtersets import FilterSet
>>> class MyFilterSet(FilterSet):
...     foo = Filter(forms.CharField())
...     bar = Filter(forms.IntegerField())
  • form_field (Field) – Instance of Django’s forms.Field which will be used to clean the filter value as provided in the queryset. For example if field is IntegerField, this filter will make sure to convert the filtering value to integer before creating a FilterSpec.
  • lookups (list, optional) – List of strings of allowed lookups for this filter. By default all supported lookups are allowed.
  • default_lookup (str, optional) – If the lookup is not provided in the querystring lookup key, this lookup will be used. By default exact lookup is used. For example the default lookup is used when querystring key is user__profile__email which is missing the lookup so exact will be used.
  • is_default (bool, optional) – Boolean specifying if this filter should be used as a default filter in the parent FilterSet. By default it is False. Primarily this is used when querystring lookup key refers to a nested FilterSet however it does not specify which filter to use. For example lookup key user__profile intends to filter something in the user’s profile however it does not specify by which field to filter on. In that case the default filter within profile FilterSet will be used. At most, one default filter should be provided in the FilterSet.
  • no_lookup (bool, optional) – When True, this filter does not allow to explicitly specify lookups in the URL. For example id__gt will not be allowed. This is useful when a given filter should only support a single lookup and that lookup name should not be exposed in the URL. This is of particular use when defining custom callable filters. By default it is False.

Field – Django form field which is provided in initialization which should be used to validate data as provided in the querystring


str – Default lookup to be used as provided in initialization


bool – If this filter should be a default filter as provided in initialization


str – If this filter should not support explicit lookups as provided in initialization

clean_value(value, lookup)[source]

Clean the filter value as appropriate for the given lookup.

  • value (str) – Filter value as given in the querystring to be validated and cleaned by using appropriate Django form field
  • lookup (str) – Name of the lookup

See also



Get the form field for a particular lookup.

This method does not blindly return form_field attribute since some lookups require to use different validations. For example if the form_field is CharField but the lookup is isnull, it makes more sense to use BooleanField as form field.

Parameters:lookup (str) – Name of the lookup
Returns:Instantiated form field appropriate for the given lookup.
Return type:Field

Get the FilterSpec for the provided config.

Parameters:config (LookupConfig) – Lookup configuration for which to build FilterSpec. The lookup should be a leaf configuration otherwise ValidationError is raised.
Returns:spec constructed from the given configuration.
Return type:FilterSpec

Cached property for getting lookups this filter supports

The reason why we need as a property is because lookups cant be hardcoded. There are 3 main distinct possibilities which drive which lookups are supported:

  • lookups were explicitly provided in the filter instantiation in which case we use those lookups. For example:

    >>> f = Filter(forms.CharField(), lookups=['exact', 'contains'])
  • when filter is already bound to a parent filterset and root filterset has a defined filter_backend we use supported lookups as explicitly defined by the backend. This is necessary since different backends support different sets of lookups.

  • when nether lookups are explicitly provided and filter is not bound yet we have no choice but not support any lookups and so we use empty set as supported lookups


Get custom representation of the filter

The representation includes the following information:

  • filter class name
  • source name (same as source) when filter is bound to parent
  • primary form field (same as form_field)
  • which lookups this filter supports
  • default lookup (same as default_lookup)
  • if the filter is a default filter (same as is_default) when filter is bound to parent
  • if this filter does not support explicit lookups (same as no_lookup)

Decorator for specifying form field for a custom callable filter on the filter callable method


>>> class MyFilterCallable(CallableFilter):
...     @form_field_for_filter(forms.CharField())
...     def filter_foo_for_django(self, queryset, spec):
...         return queryset
Parameters:form_field (Field) – Django form field which should be used for the decorated custom callable filter
Returns:Function which can be used to decorate a class method
Return type:func