|
| 1 | +""" |
| 2 | +cl_sii "extras" / Django-Filter. |
| 3 | +
|
| 4 | +(for Django views and DRF views) |
| 5 | +""" |
| 6 | + |
| 7 | +from __future__ import annotations |
| 8 | + |
| 9 | + |
| 10 | +try: |
| 11 | + import django_filters |
| 12 | +except ImportError as exc: # pragma: no cover |
| 13 | + raise ImportError("Package 'django-filter' is required to use this module.") from exc |
| 14 | + |
| 15 | +from copy import deepcopy |
| 16 | +from typing import ClassVar, Mapping, Tuple, Type |
| 17 | + |
| 18 | +import django.db.models |
| 19 | +import django.forms |
| 20 | + |
| 21 | +import cl_sii.extras.dj_form_fields |
| 22 | +import cl_sii.extras.dj_model_fields |
| 23 | + |
| 24 | + |
| 25 | +FILTER_FOR_DBFIELD_DEFAULTS: Mapping[Type[django.db.models.Field], Mapping[str, object]] |
| 26 | +FILTER_FOR_DBFIELD_DEFAULTS = deepcopy(django_filters.filterset.FILTER_FOR_DBFIELD_DEFAULTS) |
| 27 | + |
| 28 | + |
| 29 | +class RutFilter(django_filters.filters.CharFilter): |
| 30 | + """ |
| 31 | + Matches on a RUT. |
| 32 | +
|
| 33 | + Used with :class:`cl_sii.extras.dj_form_fields.RutField` by default. |
| 34 | +
|
| 35 | + .. seealso:: |
| 36 | + - https://django-filter.readthedocs.io/en/stable/ref/filters.html |
| 37 | + - https://github.com/carltongibson/django-filter/blob/24.2/docs/ref/filters.txt |
| 38 | + """ |
| 39 | + |
| 40 | + field_class: ClassVar[Type[django.forms.Field]] |
| 41 | + field_class = cl_sii.extras.dj_form_fields.RutField |
| 42 | + |
| 43 | + |
| 44 | +FILTER_FOR_DBFIELD_DEFAULTS = { |
| 45 | + **FILTER_FOR_DBFIELD_DEFAULTS, |
| 46 | + cl_sii.extras.dj_model_fields.RutField: {'filter_class': RutFilter}, |
| 47 | +} |
| 48 | + |
| 49 | + |
| 50 | +class SiiFilterSet(django_filters.filterset.FilterSet): |
| 51 | + """ |
| 52 | + Custom filterset with extra database field mappings. |
| 53 | +
|
| 54 | + This class serves as a base class for filtersets that additionally need to |
| 55 | + support filtering one of the following database fields: |
| 56 | + - :class:`cl_sii.extras.dj_model_fields.RutField` |
| 57 | +
|
| 58 | + .. seealso:: |
| 59 | + - https://django-filter.readthedocs.io/en/main/ref/filterset.html |
| 60 | + - https://github.com/carltongibson/django-filter/blob/24.2/docs/ref/filterset.txt |
| 61 | + """ |
| 62 | + |
| 63 | + FILTER_DEFAULTS: ClassVar[Mapping[Type[django.db.models.Field], Mapping[str, object]]] |
| 64 | + FILTER_DEFAULTS = FILTER_FOR_DBFIELD_DEFAULTS |
| 65 | + |
| 66 | + @classmethod |
| 67 | + def filter_for_lookup( |
| 68 | + cls, field: django.db.models.Field, lookup_type: str |
| 69 | + ) -> Tuple[Type[django_filters.filters.Filter], Mapping[str, object]]: |
| 70 | + filter_class, params = super().filter_for_lookup(field, lookup_type) |
| 71 | + |
| 72 | + # Override RUT containment lookups. |
| 73 | + if isinstance(field, cl_sii.extras.dj_model_fields.RutField) and lookup_type in ( |
| 74 | + 'contains', |
| 75 | + 'icontains', |
| 76 | + ): |
| 77 | + filter_class, params = django_filters.filters.CharFilter, {} |
| 78 | + |
| 79 | + return filter_class, params |
0 commit comments