/
views.py
76 lines (65 loc) · 2.77 KB
/
views.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# encoding: utf-8
from urllib.parse import parse_qsl
from django.apps import apps
from django.contrib.admin.utils import prepare_lookup_value
from django.http import Http404, JsonResponse
from django.views.generic.list import BaseListView
from cool.core.utils import get_search_results
from cool.settings import cool_settings
class CoolAutocompleteJsonView(BaseListView):
"""
外键自动提示view
"""
paginate_by = 20
def get(self, request, *args, **kwargs):
"""
Return a JsonResponse with search results of the form:
{
results: [{id: "123", text: "foo"}],
pagination: {more: true}
}
"""
app_label = request.GET['app_label']
model_name = request.GET['model_name']
limit_choices_to = request.GET.get('limit_choices_to', None)
to_field_name = request.GET.get('to_field_name', 'pk')
term = request.GET.get('term', '')
if not self.has_perm(request, app_label, model_name):
return JsonResponse({'error': '403 Forbidden'}, status=403)
try:
self.model = apps.get_model(app_label, model_name)
except LookupError:
return JsonResponse({'error': '403 Forbidden'}, status=403)
queryset = self.get_queryset()
filters = dict()
if limit_choices_to:
for key, value in parse_qsl(limit_choices_to):
filters[key] = prepare_lookup_value(key, value)
if filters:
queryset = queryset.filter(**filters)
get_search_fields = getattr(self.model, 'get_search_fields')
search_fields = None
if get_search_fields and callable(get_search_fields):
search_fields = get_search_fields()
if not search_fields:
raise Http404('%s must have get_search_fields for the autocomplete_view.' % type(self.model).__name__)
queryset, search_use_distinct = get_search_results(queryset, term, search_fields, self.model)
if search_use_distinct:
queryset = queryset.distinct()
context = self.get_context_data(object_list=queryset)
return JsonResponse({
'results': [
{'id': str(getattr(obj, to_field_name)), 'text': str(obj)}
for obj in context['object_list']
],
'pagination': {'more': context['page_obj'].has_next()},
})
@classmethod
def has_perm(cls, request, app_label, model_name):
if cool_settings.ADMIN_AUTOCOMPLETE_CHECK_PERM:
return (
request.user.has_perm('%s.%s_%s' % (app_label, 'view', model_name)) or
request.user.has_perm('%s.%s_%s' % (app_label, 'change', model_name))
)
else:
return request.user.is_staff and request.user.is_active