diff --git a/netbox/core/models/jobs.py b/netbox/core/models/jobs.py index fab4e00a0..73bcd13d6 100644 --- a/netbox/core/models/jobs.py +++ b/netbox/core/models/jobs.py @@ -39,7 +39,8 @@ class Job(models.Model): ) object = GenericForeignKey( ct_field='object_type', - fk_field='object_id' + fk_field='object_id', + for_concrete_model=False ) name = models.CharField( max_length=200 diff --git a/netbox/extras/views.py b/netbox/extras/views.py index cca9cab1c..bbc00d045 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -819,18 +819,9 @@ class ReportListView(ContentTypePermissionRequiredMixin, View): def get(self, request): report_modules = ReportModule.objects.restrict(request.user) - jobs = { - r.name: r - for r in Job.objects.filter( - object_type=ContentType.objects.get_by_natural_key('extras', 'reportmodule'), - status__in=JobStatusChoices.TERMINAL_STATE_CHOICES - ).order_by('name', '-created').distinct('name').defer('data') - } - return render(request, 'extras/report_list.html', { 'model': ReportModule, 'report_modules': report_modules, - 'jobs': jobs, }) @@ -986,18 +977,9 @@ class ScriptListView(ContentTypePermissionRequiredMixin, View): def get(self, request): script_modules = ScriptModule.objects.restrict(request.user) - jobs = { - r.name: r - for r in Job.objects.filter( - object_type=ContentType.objects.get_by_natural_key('extras', 'scriptmodule'), - status__in=JobStatusChoices.TERMINAL_STATE_CHOICES - ).order_by('name', '-created').distinct('name').defer('data') - } - return render(request, 'extras/script_list.html', { 'model': ScriptModule, 'script_modules': script_modules, - 'jobs': jobs, }) diff --git a/netbox/netbox/models/features.py b/netbox/netbox/models/features.py index 5573b1abc..cf141d987 100644 --- a/netbox/netbox/models/features.py +++ b/netbox/netbox/models/features.py @@ -9,9 +9,9 @@ from django.db.models.signals import class_prepared from django.dispatch import receiver from django.utils import timezone from django.utils.translation import gettext as _ - from taggit.managers import TaggableManager +from core.choices import JobStatusChoices from extras.choices import CustomFieldVisibilityChoices, ObjectChangeActionChoices from extras.utils import is_taggable, register_features from netbox.registry import registry @@ -302,12 +302,24 @@ class JobsMixin(models.Model): jobs = GenericRelation( to='core.Job', content_type_field='object_type', - object_id_field='object_id' + object_id_field='object_id', + for_concrete_model=False ) class Meta: abstract = True + def get_latest_jobs(self): + """ + Return a dictionary mapping of the most recent jobs for this instance. + """ + return { + job.name: job + for job in self.jobs.filter( + status__in=JobStatusChoices.TERMINAL_STATE_CHOICES + ).order_by('name', '-created').distinct('name').defer('data') + } + class JournalingMixin(models.Model): """ diff --git a/netbox/templates/extras/report_list.html b/netbox/templates/extras/report_list.html index ea47b7886..e9eef966c 100644 --- a/netbox/templates/extras/report_list.html +++ b/netbox/templates/extras/report_list.html @@ -49,56 +49,58 @@
- {% for report_name, report in module.reports.items %} - {% with last_result=jobs|get_key:report.name %} -