Filtering and Ordering¶
During a get list view, it is useful to be able to filter or rearrange the results. Django-Conduit provides a few helpful properties and hooks to to filter your resources.
Server Side Filters to Limit Access¶
The default_filters dict on a ModelResource’s Meta class will apply the listed queryset filters before fetching results. The keys in default_filters ought to be a valid Queryset filter method for the specified model. Here is an example that only returns Foo objects that have a name starting with the the word ‘lamp’:
class FooResource(ModelResource):
class Meta(ModelResource.Meta):
default_filters = {
'name__startswith': 'lamp'
}
The default filters will eventually be applied to the queryset during the apply_filters method, resulting in something like this:
filtered_instances = Foo.objects.filter(name__startswith='lamp')
Client Side Filtering with Get Params¶
API consumers often need to be able to filter against certain resource fields using GET parameters. Filtering is enabled by specifying the allowed_filters array. The array takes a series of Queryset filter keywords:
class FooResource(ModelResource):
class Meta(ModelResource.Meta):
allowed_filters = [
'name__icontains',
'created__lte',
'created__gte',
'bar__name'
]
In the above example, API consumers will be allowed to get Foo objects by searching for strings in the Foo name, or by finding Foos created before or after a given datetime.
Note
Each Queryset filter has to be specified using the entire filter name. While verbose, this allows custom or related field parameters such as bar__name to be easily specified.
Ordering Results¶
If you want to specify the default order for objected, returned, you can simply specify the order_by string using the default_ordering Meta field:
class FooResource(ModelResource):
class Meta(ModelResource.Meta):
default_ordering='-created'
The value of default_ordering should be the same one you would use when performing order_by on a queryset. The above example will result in the following operation:
Foo.objects.order_by('-created')
To allow API consumers to order the results, the allowed_ordering field is an array of valid ordering keys:
class FooResource(ModelResource):
class Meta(ModelResource.Meta):
allowed_ordering = [
'created',
'-created'
]
Note how the forward and reverse string both have to be specified. This is to provide precise control over client ordering values.
How Filters & Ordering are Applied¶
Filtering and ordering happens inside two steps in the default conduit pipeline. The first happens inside process_filters. To determine order, first the method looks for an order_by GET parameter. If none are specified, it defaults to the default_ordering attribute. If the order_by parameter is not a valid value, the client receives a 400.
The filters start with the default_filters dictionary. This dictionary is then updated from filters specified in the GET parameters, provided they are specified in allowed_filters.
After the order_by and filters are determined, their values are sent forward in the kwargs dictionary where they are picked up again in pre_get_list. This is the method that first applies the kwargs['order_by'] value, and then applies the values inside kwargs['filters']. It stores the ordered and filtered queryset inside of kwargs['objs']. The objects are then subject to authorization limits and paginated inside get_list before the final set of objects is determined.