Coverage for apis_core/apis_entities/views.py: 42%

24 statements  

« prev     ^ index     » next       coverage.py v7.14.1, created at 2026-07-06 07:19 +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 

5 

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 

9 

10 

11class EntitiesAutocomplete(autocomplete.Select2QuerySetView): 

12 """ 

13 This endpoint allows us to use autocomplete over multiple model classes. 

14 It takes a parameter `entities` which is a list of ContentType natural 

15 keys and searches for the query in all instances of those entities 

16 (using `generate_search_filter`, which means it uses a different search 

17 approach for every model). 

18 The return values of the endpoint are then prefixed with the id of the 

19 contenttype of the results, separated by an underscore. 

20 

21 Example: 

22 Using this endpoint with the parameters: 

23 

24 ?entities=apis_ontology.person&entities=apis_ontology.place&q=ammer 

25 

26 gives you all the persons and places that have `ammer` in their names 

27 and labels. 

28 """ 

29 

30 def get_result_value(self, result) -> str: 

31 content_type = ContentType.objects.get_for_model(result) 

32 return f"{content_type.id}_" + super().get_result_value(result) 

33 

34 def get_queryset(self): 

35 q = Q() 

36 entities = [] 

37 for entity in self.request.GET.getlist("entities"): 

38 app_label, model = entity.split(".") 

39 content_type = get_object_or_404( 

40 ContentType, app_label=app_label, model=model 

41 ) 

42 entities.append(content_type) 

43 if not entities: 

44 entities = get_entity_content_types() 

45 for content_type in entities: 

46 name = RootObject.objects_inheritance.get_queryset()._get_ancestors_path( 

47 content_type.model_class() 

48 ) 

49 q |= Q(**{f"{name}__isnull": False}) & generate_search_filter( 

50 content_type.model_class(), self.q, prefix=f"{name}__" 

51 ) 

52 return RootObject.objects_inheritance.select_subclasses().filter(q)