122 lines
3.9 KiB
Python
122 lines
3.9 KiB
Python
import itertools
|
|
from collections import OrderedDict
|
|
from functools import update_wrapper
|
|
|
|
from django.contrib import admin
|
|
from django.urls import reverse
|
|
from django.shortcuts import render, redirect
|
|
from django.utils.safestring import mark_safe
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from .dashboard import *
|
|
from .options import *
|
|
from ..core import accounts, services
|
|
|
|
|
|
# monkey-patch admin.site in order to porvide some extra admin urls
|
|
|
|
urls = []
|
|
def register_url(pattern, view, name=""):
|
|
global urls
|
|
urls.append((pattern, view, name))
|
|
admin.site.register_url = register_url
|
|
|
|
|
|
site_get_urls = admin.site.get_urls
|
|
def get_urls():
|
|
def wrap(view, cacheable=False):
|
|
def wrapper(*args, **kwargs):
|
|
return admin.site.admin_view(view, cacheable)(*args, **kwargs)
|
|
wrapper.admin_site = admin.site
|
|
return update_wrapper(wrapper, view)
|
|
global urls
|
|
extra_patterns = []
|
|
for pattern, view, name in urls:
|
|
extra_patterns.append(
|
|
url(pattern, wrap(view), name=name)
|
|
)
|
|
return site_get_urls() + extra_patterns
|
|
admin.site.get_urls = get_urls
|
|
|
|
|
|
def get_model(model_name, model_name_map):
|
|
try:
|
|
return model_name_map[model_name.lower()]
|
|
except KeyError:
|
|
return
|
|
|
|
|
|
def search(request):
|
|
query = request.GET.get('q', '')
|
|
search_term = query
|
|
models = set()
|
|
selected_models = set()
|
|
model_name_map = {}
|
|
for service in itertools.chain(services, accounts):
|
|
if service.search:
|
|
models.add(service.model)
|
|
model_name_map[service.model._meta.model_name] = service.model
|
|
|
|
# Account direct access
|
|
if search_term.endswith('!'):
|
|
from ..contrib.accounts.models import Account
|
|
search_term = search_term.replace('!', '')
|
|
try:
|
|
account = Account.objects.get(username=search_term)
|
|
except Account.DoesNotExist:
|
|
pass
|
|
else:
|
|
account_url = reverse('admin:accounts_account_change', args=(account.pk,))
|
|
return redirect(account_url)
|
|
# Search for specific model
|
|
elif ':' in search_term:
|
|
new_search_term = []
|
|
for part in search_term.split():
|
|
if ':' in part:
|
|
model_name, term = part.split(':')
|
|
model = get_model(model_name, model_name_map)
|
|
# Retry with singular version
|
|
if model is None and model_name.endswith('s'):
|
|
model = get_model(model_name[:-1], model_name_map)
|
|
if model is None:
|
|
new_search_term.append(':'.join((model_name, term)))
|
|
else:
|
|
selected_models.add(model)
|
|
new_search_term.append(term)
|
|
else:
|
|
new_search_term.append(part)
|
|
search_term = ' '.join(new_search_term)
|
|
if selected_models:
|
|
models = selected_models
|
|
results = OrderedDict()
|
|
models = sorted(models, key=lambda m: m._meta.verbose_name_plural.lower())
|
|
total = 0
|
|
for model in models:
|
|
try:
|
|
modeladmin = admin.site._registry[model]
|
|
except KeyError:
|
|
pass
|
|
else:
|
|
qs = modeladmin.get_queryset(request)
|
|
qs, search_use_distinct = modeladmin.get_search_results(request, qs, search_term)
|
|
if search_use_distinct:
|
|
qs = qs.distinct()
|
|
num = len(qs)
|
|
if num:
|
|
total += num
|
|
results[model._meta] = qs
|
|
title = _("{total} search results for '<tt>{query}</tt>'").format(total=total, query=query)
|
|
context = {
|
|
'title': mark_safe(title),
|
|
'total': total,
|
|
'columns': min(int(total/17), 3),
|
|
'query': query,
|
|
'search_term': search_term,
|
|
'results': results,
|
|
'search_autofocus': True,
|
|
}
|
|
return render(request, 'admin/orchestra/search.html', context)
|
|
|
|
|
|
admin.site.register_url(r'^search/$', search, 'orchestra_search_view')
|