Coverage for apis_core/apis_entities/views.py: 48%
27 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
1from dal import autocomplete
2from django.contrib.contenttypes.models import ContentType
3from django.db.models import Q
4from django.shortcuts import get_object_or_404
6from apis_core.apis_entities.utils import get_entity_content_types
7from apis_core.apis_metainfo.models import RootObject
8from apis_core.generic.helpers import generate_search_filter
9from apis_core.generic.views import List
12class EntitiesAutocomplete(autocomplete.Select2QuerySetView):
13 """
14 This endpoint allows us to use autocomplete over multiple model classes.
15 It takes a parameter `entities` which is a list of ContentType natural
16 keys and searches for the query in all instances of those entities
17 (using `generate_search_filter`, which means it uses a different search
18 approach for every model).
19 The return values of the endpoint are then prefixed with the id of the
20 contenttype of the results, separated by an underscore.
22 Example:
23 Using this endpoint with the parameters:
25 ?entities=apis_ontology.person&entities=apis_ontology.place&q=ammer
27 gives you all the persons and places that have `ammer` in their names
28 and labels.
29 """
31 def get_result_value(self, result) -> str:
32 content_type = ContentType.objects.get_for_model(result)
33 return f"{content_type.id}_" + super().get_result_value(result)
35 def get_queryset(self):
36 q = Q()
37 entities = []
38 for entity in self.request.GET.getlist("entities"):
39 app_label, model = entity.split(".")
40 content_type = get_object_or_404(
41 ContentType, app_label=app_label, model=model
42 )
43 entities.append(content_type)
44 if not entities:
45 entities = get_entity_content_types()
46 for content_type in entities:
47 name = RootObject.objects_inheritance.get_queryset()._get_ancestors_path(
48 content_type.model_class()
49 )
50 q |= Q(**{f"{name}__isnull": False}) & generate_search_filter(
51 content_type.model_class(), self.q, prefix=f"{name}__"
52 )
53 return RootObject.objects_inheritance.select_subclasses().filter(q)
56class E53_PlaceMap(List):
57 template_name_suffix = "_map"