Coverage for apis_core/apis_entities/filtersets.py: 0%
36 statements
« prev ^ index » next coverage.py v7.5.3, created at 2025-06-25 10:00 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2025-06-25 10:00 +0000
1import django_filters
2from django.apps import apps
3from django.conf import settings
4from django.db import models
5from django.forms import DateInput
6from django.utils.encoding import force_str
7from simple_history.utils import get_history_manager_for_model
9from apis_core.generic.filtersets import GenericFilterSet
10from apis_core.generic.helpers import default_search_fields, generate_search_filter
13class ModelSearchFilter(django_filters.CharFilter):
14 """
15 This filter is a customized CharFilter that
16 uses the `generate_search_filter` method to
17 adapt the search filter to the model that is
18 searched.
19 It also extracts sets the help text based on
20 the fields searched.
21 """
23 def __init__(self, *args, **kwargs):
24 model = kwargs.pop("model", None)
25 super().__init__(*args, **kwargs)
27 if model is not None and "help_text" not in self.extra:
28 field_names = [field.verbose_name for field in default_search_fields(model)]
29 # use force_str on the fields verbose names to convert
30 # lazy instances to string and join the results
31 fields = ", ".join(map(force_str, field_names))
32 self.extra["help_text"] = f"Search in fields: {fields}"
34 def filter(self, qs, value):
35 return qs.filter(generate_search_filter(qs.model, value))
38def changed_since(queryset, name, value):
39 history = get_history_manager_for_model(queryset.model)
40 ids = history.filter(history_date__gt=value).values_list("id", flat=True)
41 return queryset.filter(pk__in=ids)
44class AbstractEntityFilterSet(GenericFilterSet):
45 class Meta(GenericFilterSet.Meta):
46 filter_overrides = {
47 models.CharField: {
48 "filter_class": django_filters.CharFilter,
49 "extra": lambda f: {
50 "lookup_expr": "icontains",
51 },
52 },
53 }
55 def __init__(self, *args, **kwargs):
56 super().__init__(*args, **kwargs)
57 if model := getattr(self.Meta, "model", False):
58 self.filters["search"] = ModelSearchFilter(model=model)
59 self.filters.move_to_end("search", False)
61 if "apis_core.history" in settings.INSTALLED_APPS:
62 self.filters["changed_since"] = django_filters.DateFilter(
63 label="Changed since",
64 widget=DateInput(attrs={"type": "date"}),
65 method=changed_since,
66 )
68 if apps.is_installed("apis_core.relations"):
69 from apis_core.relations.filters import RelationFilter
71 self.filters["relation"] = RelationFilter()