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
« 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
7class AutocompleteJsonView(BaseListView):
8 """Handle AutocompleteWidget's AJAX requests for data."""
10 paginate_by = 20
11 admin_site = None
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)
29 if not self.has_perm(request):
30 raise PermissionDenied
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 )
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)}
51 def get_paginator(self, *args, **kwargs):
52 """Use the ModelAdmin's paginator."""
53 return self.model_admin.get_paginator(self.request, *args, **kwargs)
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
66 def process_request(self, request):
67 """
68 Validate request integrity, extract and return request parameters.
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.
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
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
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
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 )
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
118 return term, model_admin, source_field, to_field_name
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)