Ajoutez des fichiers projet.
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
from django.apps import apps
|
||||
from django.core.exceptions import FieldDoesNotExist, PermissionDenied
|
||||
from django.http import Http404, JsonResponse
|
||||
from django.views.generic.list import BaseListView
|
||||
|
||||
|
||||
class AutocompleteJsonView(BaseListView):
|
||||
"""Handle AutocompleteWidget's AJAX requests for data."""
|
||||
paginate_by = 20
|
||||
admin_site = None
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
"""
|
||||
Return a JsonResponse with search results as defined in
|
||||
serialize_result(), by default:
|
||||
{
|
||||
results: [{id: "123" text: "foo"}],
|
||||
pagination: {more: true}
|
||||
}
|
||||
"""
|
||||
self.term, self.model_admin, self.source_field, to_field_name = self.process_request(request)
|
||||
|
||||
if not self.has_perm(request):
|
||||
raise PermissionDenied
|
||||
|
||||
self.object_list = self.get_queryset()
|
||||
context = self.get_context_data()
|
||||
return JsonResponse({
|
||||
'results': [
|
||||
self.serialize_result(obj, to_field_name)
|
||||
for obj in context['object_list']
|
||||
],
|
||||
'pagination': {'more': context['page_obj'].has_next()},
|
||||
})
|
||||
|
||||
def serialize_result(self, obj, to_field_name):
|
||||
"""
|
||||
Convert the provided model object to a dictionary that is added to the
|
||||
results list.
|
||||
"""
|
||||
return {'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
|
||||
|
||||
def get_paginator(self, *args, **kwargs):
|
||||
"""Use the ModelAdmin's paginator."""
|
||||
return self.model_admin.get_paginator(self.request, *args, **kwargs)
|
||||
|
||||
def get_queryset(self):
|
||||
"""Return queryset based on ModelAdmin.get_search_results()."""
|
||||
qs = self.model_admin.get_queryset(self.request)
|
||||
qs = qs.complex_filter(self.source_field.get_limit_choices_to())
|
||||
qs, search_use_distinct = self.model_admin.get_search_results(self.request, qs, self.term)
|
||||
if search_use_distinct:
|
||||
qs = qs.distinct()
|
||||
return qs
|
||||
|
||||
def process_request(self, request):
|
||||
"""
|
||||
Validate request integrity, extract and return request parameters.
|
||||
|
||||
Since the subsequent view permission check requires the target model
|
||||
admin, which is determined here, raise PermissionDenied if the
|
||||
requested app, model or field are malformed.
|
||||
|
||||
Raise Http404 if the target model admin is not configured properly with
|
||||
search_fields.
|
||||
"""
|
||||
term = request.GET.get('term', '')
|
||||
try:
|
||||
app_label = request.GET['app_label']
|
||||
model_name = request.GET['model_name']
|
||||
field_name = request.GET['field_name']
|
||||
except KeyError as e:
|
||||
raise PermissionDenied from e
|
||||
|
||||
# Retrieve objects from parameters.
|
||||
try:
|
||||
source_model = apps.get_model(app_label, model_name)
|
||||
except LookupError as e:
|
||||
raise PermissionDenied from e
|
||||
|
||||
try:
|
||||
source_field = source_model._meta.get_field(field_name)
|
||||
except FieldDoesNotExist as e:
|
||||
raise PermissionDenied from e
|
||||
try:
|
||||
remote_model = source_field.remote_field.model
|
||||
except AttributeError as e:
|
||||
raise PermissionDenied from e
|
||||
try:
|
||||
model_admin = self.admin_site._registry[remote_model]
|
||||
except KeyError as e:
|
||||
raise PermissionDenied from e
|
||||
|
||||
# Validate suitability of objects.
|
||||
if not model_admin.get_search_fields(request):
|
||||
raise Http404(
|
||||
'%s must have search_fields for the autocomplete_view.' %
|
||||
type(model_admin).__qualname__
|
||||
)
|
||||
|
||||
to_field_name = getattr(source_field.remote_field, 'field_name', remote_model._meta.pk.attname)
|
||||
to_field_name = remote_model._meta.get_field(to_field_name).attname
|
||||
if not model_admin.to_field_allowed(request, to_field_name):
|
||||
raise PermissionDenied
|
||||
|
||||
return term, model_admin, source_field, to_field_name
|
||||
|
||||
def has_perm(self, request, obj=None):
|
||||
"""Check if user has permission to access the related model."""
|
||||
return self.model_admin.has_view_permission(request, obj=obj)
|
Reference in New Issue
Block a user