Django-filter is a powerful tool, but the documentation is a little sparse. If you want to see examples of custom Filters you have to dive into the source code.

I recently wanted to add a filter for methods on a custom QuerySet . Unlike custom managers, custom QuerySets allow you to chain methods. You can read this introduction or refer to the official documentation (at the time of this writing 1.7 wasn't released yet). Here is a short example of what's possible:

Product . products . in_stock () . price_below ( 100 ) . has_color ( 'red' )

You get the idea, it's just a convenient way to write shorter code.

So I had my methods and wanted to use them with django-filter, but it took a while to figure out how. After some digging I took the DateRangeField class as a blueprint (0.7 source) and came up with this filter:

class QuerySetFilter ( django_filters . ChoiceFilter ): def __init__ ( self , options , * args , ** kwargs ): self . options = options kwargs [ 'choices' ] = [ ( key , value [ 0 ]) for key , value in six . iteritems ( self . options )] super ( QuerySetFilter , self ) . __init__ ( * args , ** kwargs ) def filter ( self , qs , value ): config = self . options [ value ][ 1 ] method = config . get ( 'method' , '' ) args = config . get ( 'args' , ()) kwargs = config . get ( 'kwargs' , {}) if method == '' : return qs elif not hasattr ( qs , method ): raise Exception ( "Improperly configured" , "Unknown QuerySet method %s " % method ) return getattr ( qs , method )( * args , ** kwargs )

To use this QuerySetFilter you can create a FilterSet that is configured like this:

class ProductFilterSet ( django_filters . FilterSet ): product_choices = { '' : ( '---------' , '' ), 'fresh' : ( 'Fresh' , { 'method' : 'age_group' 'args' : ( 'fresh' , ), }), 'regular' : ( 'Regular' , { 'method' : 'age_group' , 'args' : ( 'regular' , ), }), 'old' : ( 'Old' , { 'method' : 'age_group' , 'args' : ( 'old' , ), }), } product_group = QuerySetFilter ( product_choices , label = 'Product age choices' ) class Meta : model = Product fields = [ 'product_group' , ]

The configuration dict is made of key-choice pairs. Each choice is a two-tuple of label-queryconfig. The queryconfig should define a method key, which is the QuerySet method that will be used. Optional args and kwargs values are passed to the method call.