From 50c2397924e9aadb64eb0a2924f30944175ab8a0 Mon Sep 17 00:00:00 2001 From: Marc Aymerich Date: Tue, 18 Nov 2014 18:41:44 +0000 Subject: [PATCH] Improved performance of resource data changelist --- TODO.md | 5 +--- orchestra/apps/orchestration/methods.py | 6 ++-- orchestra/apps/resources/admin.py | 38 ++++++++++++++++++++----- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/TODO.md b/TODO.md index 82ed92c6..1e89fe86 100644 --- a/TODO.md +++ b/TODO.md @@ -175,12 +175,9 @@ Remember that, as always with QuerySets, any subsequent chained methods which im * admin systemuser home/directory, add default home and empty directory with has_shell on admin -* Backendlog doesn't show during execution, transaction isolation or what? - * Resource used_list_display=True, allocated_list_displat=True, allow resources to show up on list_display * Move plugins back from apps to orchestra main app - -* BackendLog.updated_at (tasks that run over several minutes when finished they do not appear first on the changelist) +* BackendLog.updated_at (tasks that run over several minutes when finished they do not appear first on the changelist) (like celery tasks.when) diff --git a/orchestra/apps/orchestration/methods.py b/orchestra/apps/orchestration/methods.py index 637d6ec7..b9eeba69 100644 --- a/orchestra/apps/orchestration/methods.py +++ b/orchestra/apps/orchestration/methods.py @@ -112,11 +112,12 @@ def Python(backend, log, server, cmds, async=False): script = json.dumps(script, indent=4).replace('"', '') log.script = '\n'.join([log.script, script]) log.save(update_fields=['script']) - stdout = '' try: for cmd in cmds: result = cmd(server) - stdout += str(result) + log.stdout += str(result) + if async: + log.save(update_fields=['stdout']) except: log.exit_code = 1 log.state = log.FAILURE @@ -124,5 +125,4 @@ def Python(backend, log, server, cmds, async=False): else: log.exit_code = 0 log.state = log.SUCCESS - log.stdout += stdout log.save() diff --git a/orchestra/apps/resources/admin.py b/orchestra/apps/resources/admin.py index 7034c6b4..694de216 100644 --- a/orchestra/apps/resources/admin.py +++ b/orchestra/apps/resources/admin.py @@ -1,7 +1,9 @@ +from django.conf.urls import patterns, url from django.contrib import admin, messages from django.contrib.admin.utils import unquote from django.contrib.contenttypes import generic from django.core.urlresolvers import reverse +from django.shortcuts import redirect from django.utils.functional import cached_property from django.utils.safestring import mark_safe from django.utils.translation import ungettext, ugettext, ugettext_lazy as _ @@ -95,13 +97,25 @@ class ResourceDataAdmin(ExtendedModelAdmin): actions = (run_monitor,) change_view_actions = actions ordering = ('-updated_at',) - list_select_related = ('resource',) + list_select_related = ('resource__content_type',) prefetch_related = ('content_object',) resource_link = admin_link('resource') content_object_link = admin_link('content_object') display_updated = admin_date('updated_at', short_description=_("Updated")) + def get_urls(self): + """Returns the additional urls for the change view links""" + urls = super(ResourceDataAdmin, self).get_urls() + admin_site = self.admin_site + opts = self.model._meta + return patterns('', + url('^(\d+)/used-monitordata/$', + admin_site.admin_view(self.used_monitordata_view), + name='%s_%s_used_monitordata' % (opts.app_label, opts.model_name) + ) + ) + urls + def display_unit(self, data): return data.unit display_unit.short_description = _("Unit") @@ -110,6 +124,21 @@ class ResourceDataAdmin(ExtendedModelAdmin): def display_used(self, data): if not data.used: return '' + url = reverse('admin:resources_resourcedata_used_monitordata', args=(data.pk,)) + return '%s' % (url, data.used) + display_used.short_description = _("Used") + display_used.admin_order_field = 'used' + display_used.allow_tags = True + + def has_add_permission(self, *args, **kwargs): + return False + + def used_monitordata_view(self, request, object_id): + """ + Does the redirect on a separated view for performance reassons + (calculate this on a changelist is expensive) + """ + data = self.get_object(request, object_id) ids = [] for dataset in data.get_monitor_datasets(): if isinstance(dataset, MonitorData): @@ -118,12 +147,7 @@ class ResourceDataAdmin(ExtendedModelAdmin): ids += dataset.values_list('id', flat=True) url = reverse('admin:resources_monitordata_changelist') url += '?id__in=%s' % ','.join(map(str, ids)) - return '%s' % (url, data.used) - display_used.short_description = _("Used") - display_used.allow_tags = True - - def has_add_permission(self, *args, **kwargs): - return False + return redirect(url) class MonitorDataAdmin(ExtendedModelAdmin):