API reference¶
- class filternaut.FilterTree(negate=False, *args, **kwargs)¶
FilterTrees instances are the result of ORing or ANDing Filter instances, or other FilterTree instances, together.
FilterTree provides a simple API for dealing with a set of filters. They may also be iterated over to gain access to the Filter instances directly.
- parse(data)¶
Have this tree of filters convert
datainto a Django Q-object.
- class filternaut.Filter(dest, **kwargs)¶
A Filter instance builds a django.db.models.Q object by pulling a value from arbitrary native data, e.g. a set of query params.
It can be ORed or ANDed together with other Filter instances in the same way Q objects can.
- clean(value)¶
Validate and normalise
valuefor use in filtering. This implementation is a no-op; subclasses may do more work here.
- parse(data)¶
Return Q-object which can be used with Django ORM.
In the general case this is just Q() wrapped around the output of
Filter.parse_to_dict(); they are different representations of the same information:parse_to_dict() -> {"id": 1} parse() -> Q(id=1)
When none-to-isnull conversion is enabled and relevant, this method returns a query which differs slightly from the dict representation:
parse_to_dict() -> {"id__in": [1, 2, None]} parse() -> Q(id__in=[1, 2]) | Q(id__isnull=True)
- parse_to_dict(data)¶
Look through the provided dict-like data for keys which match this Filter’s source. This includes keys containing lookup affixes such as ‘contains’ or ‘lte’:
{"created_date__gte": "2020-01-01..."}
If you just want to plug Filternaut into Django’s ORM, call
Filter.parse()instead.If you can’t get Filternaut to do what you want, you might have an easier time post-processing the output of
parse_to_dictand dropping it directly into the ORM’sfilter()yourself. Note that this method is only available on individual filters and not on a combination (such asFilter("a") & Filter("b")), so this approach only takes you so far.
- tree_class¶
Filters combine into FilterTree instances
alias of
FilterTree
- class filternaut.Constraint(left, *rest)¶
Base class for making collective rules over several filters.
For example, at least two of the filters must be used, or only one of the filters may be used, etc.
This class book-keeps which filters were used as it parses the incoming data. Subclasses can use this to decide whether to add or remove errors.
- class FilterUse(filter, valid, missing)¶
Subclasses will receive a
FilterUsefor each child filter. This should be used to adjust validation as necessary. SeeConstraint.apply_constraint().- filter¶
Alias for field number 0
- missing¶
Alias for field number 2
- valid¶
Alias for field number 1
- apply_constraint(report, errors)¶
Subclasses should examine how filters were used in
reportand mutateerrorsas necessary.
- class filternaut.Optional(left, *rest)¶
Filters included underneath Optional have their required=True configuration ignored as long as all those filters are missing. If some but not all are present, then required=True is observed, and those filters that are missing become invalid. If all filters under Optional have valid source data, they are valid as a whole.
This is useful for situations where you want to require one field if another is present. For example, requiring
last_nameiffirst_nameis present, but also allowing neither. In this case, you would mark both with required=True, and wrap them in Optional:Optional( Filter('first_name', required=True), Filter('last_name', required=True), )
Generally, filters underneath Optional will have required=True, however it isn’t necessary; consider adding ‘middle name’ to the above example.
- apply_constraint(report, errors)¶
Subclasses should examine how filters were used in
reportand mutateerrorsas necessary.
- class filternaut.OneOf(left, *rest)¶
Only one of the child filters can be specified at a time. Specifying two or more causes a validation error. Use like so:
filters = OneOf( Filter("foo"), Filter("bar"), Filter("baz"), )
- apply_constraint(report, errors)¶
Subclasses should examine how filters were used in
reportand mutateerrorsas necessary.
- class filternaut.filters.FieldFilter(dest, field, **kwargs)¶
FieldFilters use a django.forms.Field to clean their input value when generating a Q object.
This class is designed to be extended by subclasses which provide their own form-field instances. However, you could use it in combination with a custom field like so:
filter = FieldFilter(SpecialField(), dest='...')
- clean(value)¶
Validate and normalise
valuefor use in filtering. This implementation is a no-op; subclasses may do more work here.
- class filternaut.drf.FilternautBackend¶
FilternautBackend is a “custom generic filtering backend” for Django REST framework: http://www.django-rest-framework.org/api-guide/filtering/#custom-generic-filtering
It allows straightforward filtering of a view’s queryset using request parameters.
- filter_attr = 'filternaut_filters'¶
The host view must define filters at this attribute.
- filter_queryset(request, queryset, view)¶
Decide whether to apply the filters defined by
view.filternaut_filterson the argued queryset. If the filters parse correctly,is_validis called. If not,is_invalidis called
- is_invalid(request, queryset, errors)¶
Raise a ParseError containing the filter errors. This results in a 400 Bad Request whose body details those errors. Provided for convenience when subclassing.
- is_valid(request, queryset, query)¶
Apply Q-object
querytoqueryset. Provided for convenience when subclassing.
- class filternaut.filters.DateTimeFilter(dest, **kwargs)¶