Added filter by resource data on monitor data changelist
This commit is contained in:
parent
bea80f3edc
commit
5e4dead0c9
|
@ -75,8 +75,11 @@ class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
def display_billed_until(self, order):
|
||||
billed_until = order.billed_until
|
||||
red = False
|
||||
human = escape(naturaldate(billed_until))
|
||||
if billed_until:
|
||||
if order.service.payment_style == order.service.POSTPAY:
|
||||
if order.service.billing_period == order.service.NEVER:
|
||||
human = _("Forever")
|
||||
elif order.service.payment_style == order.service.POSTPAY:
|
||||
boundary = order.service.handler.get_billing_point(order)
|
||||
if billed_until < boundary:
|
||||
red = True
|
||||
|
@ -84,7 +87,7 @@ class OrderAdmin(AccountAdminMixin, ExtendedModelAdmin):
|
|||
red = True
|
||||
color = 'style="color:red;"' if red else ''
|
||||
return '<span title="{raw}" {color}>{human}</span>'.format(
|
||||
raw=escape(str(billed_until)), color=color, human=escape(naturaldate(billed_until)),
|
||||
raw=escape(str(billed_until)), color=color, human=human,
|
||||
)
|
||||
display_billed_until.short_description = _("billed until")
|
||||
display_billed_until.allow_tags = True
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib.admin import SimpleListFilter
|
||||
from django.db.models import Q, Prefetch, F
|
||||
from django.utils import timezone
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from . import settings
|
||||
from .models import MetricStorage
|
||||
|
||||
|
||||
|
@ -56,8 +58,13 @@ class BilledOrderListFilter(SimpleListFilter):
|
|||
metric_queryset = queryset.exclude(service__metric='').exclude(billed_on__isnull=True)
|
||||
for order in metric_queryset.prefetch_related(prefetch_valid_metrics, prefetch_billed_metric):
|
||||
if len(order.billed_metric) != 1:
|
||||
raise ValueError("Data inconsistency #metrics %i != 1." % len(order.billed_metric))
|
||||
billed_metric = order.billed_metric[0].value
|
||||
# corner case of prefetch_billed_metric: Does not always work with latests metrics
|
||||
latest = order.metrics.latest()
|
||||
if not latest:
|
||||
raise ValueError("Data inconsistency #metrics %i != 1." % len(order.billed_metric))
|
||||
billed_metric = latest.value
|
||||
else:
|
||||
billed_metric = order.billed_metric[0].value
|
||||
for metric in order.valid_metrics:
|
||||
if metric.created_on <= order.billed_on:
|
||||
raise ValueError("This value should already be filtered on the prefetch query.")
|
||||
|
@ -72,15 +79,18 @@ class BilledOrderListFilter(SimpleListFilter):
|
|||
elif self.value() == 'no':
|
||||
return queryset.exclude(billed_until__isnull=False, billed_until__gte=timezone.now())
|
||||
elif self.value() == 'pending':
|
||||
Service = apps.get_model(settings.ORDERS_SERVICE_MODEL)
|
||||
return queryset.filter(
|
||||
Q(pk__in=self.get_pending_metric_pks(queryset)) | Q(
|
||||
Q(billed_until__isnull=True) | Q(billed_until__lt=timezone.now())
|
||||
Q(billed_until__isnull=True) | Q(~Q(service__billing_period=Service.NEVER) &
|
||||
Q(billed_until__lt=timezone.now()))
|
||||
)
|
||||
)
|
||||
elif self.value() == 'not_pending':
|
||||
return queryset.exclude(
|
||||
Q(pk__in=self.get_pending_metric_pks(queryset)) | Q(
|
||||
Q(billed_until__isnull=True) | Q(billed_until__lt=timezone.now())
|
||||
Q(billed_until__isnull=True) | Q(~Q(service__billing_period=Service.NEVER) &
|
||||
Q(billed_until__lt=timezone.now()))
|
||||
)
|
||||
)
|
||||
return queryset
|
||||
|
|
|
@ -12,7 +12,7 @@ def run_monitor(modeladmin, request, queryset):
|
|||
for resource in queryset:
|
||||
rlogs = resource.monitor()
|
||||
if not async:
|
||||
logs = logs.union(set(map(str, rlogs)))
|
||||
logs = logs.union(set([str(log.pk) for log in rlogs]))
|
||||
modeladmin.log_change(request, resource, _("Run monitors"))
|
||||
if async:
|
||||
num = len(queryset)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
from urllib.parse import parse_qs
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.contrib import admin, messages
|
||||
from django.contrib.contenttypes.admin import GenericTabularInline
|
||||
|
@ -16,6 +18,7 @@ from orchestra.utils import db, sys
|
|||
from orchestra.utils.functional import cached
|
||||
|
||||
from .actions import run_monitor
|
||||
from .filters import ResourceDataListFilter
|
||||
from .forms import ResourceForm
|
||||
from .models import Resource, ResourceData, MonitorData
|
||||
|
||||
|
@ -147,25 +150,14 @@ class ResourceDataAdmin(ExtendedModelAdmin):
|
|||
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):
|
||||
ids.append(dataset.id)
|
||||
else:
|
||||
ids += dataset.values_list('id', flat=True)
|
||||
url = reverse('admin:resources_monitordata_changelist')
|
||||
url += '?id__in=%s' % ','.join(map(str, ids))
|
||||
url += '?resource_data=%s' % object_id
|
||||
return redirect(url)
|
||||
|
||||
|
||||
class MonitorDataAdmin(ExtendedModelAdmin):
|
||||
list_display = ('id', 'monitor', 'display_created', 'value', 'content_object_link')
|
||||
list_filter = ('monitor',)
|
||||
list_filter = ('monitor', ResourceDataListFilter)
|
||||
add_fields = ('monitor', 'content_type', 'object_id', 'created_at', 'value')
|
||||
fields = ('monitor', 'content_type', 'content_object_link', 'display_created', 'value')
|
||||
change_readonly_fields = fields
|
||||
|
@ -173,8 +165,23 @@ class MonitorDataAdmin(ExtendedModelAdmin):
|
|||
content_object_link = admin_link('content_object')
|
||||
display_created = admin_date('created_at', short_description=_("Created"))
|
||||
|
||||
def filter_used_monitordata(self, request, queryset):
|
||||
query_string = parse_qs(request.META['QUERY_STRING'])
|
||||
resource_data = query_string.get('resource_data')
|
||||
if resource_data:
|
||||
data = ResourceData.objects.get(pk=int(resource_data[0]))
|
||||
ids = []
|
||||
for dataset in data.get_monitor_datasets():
|
||||
if isinstance(dataset, MonitorData):
|
||||
ids.append(dataset.id)
|
||||
else:
|
||||
ids += dataset.values_list('id', flat=True)
|
||||
return queryset.filter(id__in=ids)
|
||||
return queryset
|
||||
|
||||
def get_queryset(self, request):
|
||||
queryset = super(MonitorDataAdmin, self).get_queryset(request)
|
||||
queryset = self.filter_used_monitordata(request, queryset)
|
||||
return queryset.prefetch_related('content_object')
|
||||
|
||||
|
||||
|
|
17
orchestra/contrib/resources/filters.py
Normal file
17
orchestra/contrib/resources/filters.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from django.contrib.admin import SimpleListFilter
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class ResourceDataListFilter(SimpleListFilter):
|
||||
""" Mock filter to avoid e=1 """
|
||||
title = _("Resource data")
|
||||
parameter_name = 'resource_data'
|
||||
|
||||
def lookups(self, request, model_admin):
|
||||
return ()
|
||||
|
||||
def queryset(self, request, queryset):
|
||||
return queryset
|
||||
|
||||
def choices(self, cl):
|
||||
return []
|
|
@ -225,8 +225,8 @@ class ResourceData(models.Model):
|
|||
def monitor(self, async=False):
|
||||
ids = (self.object_id,)
|
||||
if async:
|
||||
return tasks.monitor.delay(self.resource_id, ids=ids, async=async)
|
||||
return tasks.monitor(self.resource_id, ids=ids, async=async)
|
||||
return tasks.monitor.delay(self.resource_id, ids=ids)
|
||||
return tasks.monitor(self.resource_id, ids=ids)
|
||||
|
||||
def get_monitor_datasets(self):
|
||||
resource = self.resource
|
||||
|
|
Loading…
Reference in a new issue