Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/django/contrib/admin/views/autocomplete.py: 21%

58 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from django.apps import apps 

2from django.core.exceptions import FieldDoesNotExist, PermissionDenied 

3from django.http import Http404, JsonResponse 

4from django.views.generic.list import BaseListView 

5 

6 

7class AutocompleteJsonView(BaseListView): 

8 """Handle AutocompleteWidget's AJAX requests for data.""" 

9 

10 paginate_by = 20 

11 admin_site = None 

12 

13 def get(self, request, *args, **kwargs): 

14 """ 

15 Return a JsonResponse with search results as defined in 

16 serialize_result(), by default: 

17 { 

18 results: [{id: "123" text: "foo"}], 

19 pagination: {more: true} 

20 } 

21 """ 

22 ( 

23 self.term, 

24 self.model_admin, 

25 self.source_field, 

26 to_field_name, 

27 ) = self.process_request(request) 

28 

29 if not self.has_perm(request): 

30 raise PermissionDenied 

31 

32 self.object_list = self.get_queryset() 

33 context = self.get_context_data() 

34 return JsonResponse( 

35 { 

36 "results": [ 

37 self.serialize_result(obj, to_field_name) 

38 for obj in context["object_list"] 

39 ], 

40 "pagination": {"more": context["page_obj"].has_next()}, 

41 } 

42 ) 

43 

44 def serialize_result(self, obj, to_field_name): 

45 """ 

46 Convert the provided model object to a dictionary that is added to the 

47 results list. 

48 """ 

49 return {"id": str(getattr(obj, to_field_name)), "text": str(obj)} 

50 

51 def get_paginator(self, *args, **kwargs): 

52 """Use the ModelAdmin's paginator.""" 

53 return self.model_admin.get_paginator(self.request, *args, **kwargs) 

54 

55 def get_queryset(self): 

56 """Return queryset based on ModelAdmin.get_search_results().""" 

57 qs = self.model_admin.get_queryset(self.request) 

58 qs = qs.complex_filter(self.source_field.get_limit_choices_to()) 

59 qs, search_use_distinct = self.model_admin.get_search_results( 

60 self.request, qs, self.term 

61 ) 

62 if search_use_distinct: 

63 qs = qs.distinct() 

64 return qs 

65 

66 def process_request(self, request): 

67 """ 

68 Validate request integrity, extract and return request parameters. 

69 

70 Since the subsequent view permission check requires the target model 

71 admin, which is determined here, raise PermissionDenied if the 

72 requested app, model or field are malformed. 

73 

74 Raise Http404 if the target model admin is not configured properly with 

75 search_fields. 

76 """ 

77 term = request.GET.get("term", "") 

78 try: 

79 app_label = request.GET["app_label"] 

80 model_name = request.GET["model_name"] 

81 field_name = request.GET["field_name"] 

82 except KeyError as e: 

83 raise PermissionDenied from e 

84 

85 # Retrieve objects from parameters. 

86 try: 

87 source_model = apps.get_model(app_label, model_name) 

88 except LookupError as e: 

89 raise PermissionDenied from e 

90 

91 try: 

92 source_field = source_model._meta.get_field(field_name) 

93 except FieldDoesNotExist as e: 

94 raise PermissionDenied from e 

95 try: 

96 remote_model = source_field.remote_field.model 

97 except AttributeError as e: 

98 raise PermissionDenied from e 

99 try: 

100 model_admin = self.admin_site._registry[remote_model] 

101 except KeyError as e: 

102 raise PermissionDenied from e 

103 

104 # Validate suitability of objects. 

105 if not model_admin.get_search_fields(request): 

106 raise Http404( 

107 "%s must have search_fields for the autocomplete_view." 

108 % type(model_admin).__qualname__ 

109 ) 

110 

111 to_field_name = getattr( 

112 source_field.remote_field, "field_name", remote_model._meta.pk.attname 

113 ) 

114 to_field_name = remote_model._meta.get_field(to_field_name).attname 

115 if not model_admin.to_field_allowed(request, to_field_name): 

116 raise PermissionDenied 

117 

118 return term, model_admin, source_field, to_field_name 

119 

120 def has_perm(self, request, obj=None): 

121 """Check if user has permission to access the related model.""" 

122 return self.model_admin.has_view_permission(request, obj=obj)