diff --git a/netbox/extras/models/mixins.py b/netbox/extras/models/mixins.py index cb1d31837..0950324c8 100644 --- a/netbox/extras/models/mixins.py +++ b/netbox/extras/models/mixins.py @@ -8,6 +8,16 @@ __all__ = ( class PythonModuleMixin: + def get_jobs(self, name): + """ + Returns a list of Jobs associated with this specific script or report module + :param name: The class name of the script or report + :return: List of Jobs associated with this + """ + return self.jobs.filter( + name=name + ) + @property def path(self): return os.path.splitext(self.file_path)[0] diff --git a/netbox/extras/views.py b/netbox/extras/views.py index a3dd7f193..56a497f8d 100644 --- a/netbox/extras/views.py +++ b/netbox/extras/views.py @@ -1057,16 +1057,14 @@ class ReportView(ContentTypePermissionRequiredMixin, View): def get(self, request, module, name): module = get_report_module(module, request) report = module.reports[name]() + jobs = module.get_jobs(report.class_name) - object_type = ContentType.objects.get(app_label='extras', model='reportmodule') - report.result = Job.objects.filter( - object_type=object_type, - object_id=module.pk, - name=report.name, + report.result = jobs.filter( status__in=JobStatusChoices.TERMINAL_STATE_CHOICES ).first() return render(request, 'extras/report.html', { + 'job_count': jobs.count(), 'module': module, 'report': report, 'form': ReportForm(scheduling_enabled=report.scheduling_enabled), @@ -1078,6 +1076,7 @@ class ReportView(ContentTypePermissionRequiredMixin, View): module = get_report_module(module, request) report = module.reports[name]() + jobs = module.get_jobs(report.class_name) form = ReportForm(request.POST, scheduling_enabled=report.scheduling_enabled) if form.is_valid(): @@ -1086,6 +1085,7 @@ class ReportView(ContentTypePermissionRequiredMixin, View): if not get_workers_for_queue('default'): messages.error(request, "Unable to run report: RQ worker process not running.") return render(request, 'extras/report.html', { + 'job_count': jobs.count(), 'report': report, }) @@ -1103,6 +1103,7 @@ class ReportView(ContentTypePermissionRequiredMixin, View): return redirect('extras:report_result', job_pk=job.pk) return render(request, 'extras/report.html', { + 'job_count': jobs.count(), 'module': module, 'report': report, 'form': form, @@ -1117,8 +1118,10 @@ class ReportSourceView(ContentTypePermissionRequiredMixin, View): def get(self, request, module, name): module = get_report_module(module, request) report = module.reports[name]() + jobs = module.get_jobs(report.class_name) return render(request, 'extras/report/source.html', { + 'job_count': jobs.count(), 'module': module, 'report': report, 'tab': 'source', @@ -1133,13 +1136,7 @@ class ReportJobsView(ContentTypePermissionRequiredMixin, View): def get(self, request, module, name): module = get_report_module(module, request) report = module.reports[name]() - - object_type = ContentType.objects.get(app_label='extras', model='reportmodule') - jobs = Job.objects.filter( - object_type=object_type, - object_id=module.pk, - name=report.class_name - ) + jobs = module.get_jobs(report.class_name) jobs_table = JobTable( data=jobs, @@ -1149,6 +1146,7 @@ class ReportJobsView(ContentTypePermissionRequiredMixin, View): jobs_table.configure(request) return render(request, 'extras/report/jobs.html', { + 'job_count': jobs.count(), 'module': module, 'report': report, 'table': jobs_table, @@ -1232,19 +1230,16 @@ class ScriptView(ContentTypePermissionRequiredMixin, View): def get(self, request, module, name): module = get_script_module(module, request) script = module.scripts[name]() + jobs = module.get_jobs(script.class_name) form = script.as_form(initial=normalize_querydict(request.GET)) # Look for a pending Job (use the latest one by creation timestamp) - object_type = ContentType.objects.get(app_label='extras', model='scriptmodule') - script.result = Job.objects.filter( - object_type=object_type, - object_id=module.pk, - name=script.name, - ).exclude( + script.result = module.get_jobs(script.class_name).exclude( status__in=JobStatusChoices.TERMINAL_STATE_CHOICES ).first() return render(request, 'extras/script.html', { + 'job_count': jobs.count(), 'module': module, 'script': script, 'form': form, @@ -1256,6 +1251,7 @@ class ScriptView(ContentTypePermissionRequiredMixin, View): module = get_script_module(module, request) script = module.scripts[name]() + jobs = module.get_jobs(script.class_name) form = script.as_form(request.POST, request.FILES) # Allow execution only if RQ worker process is running @@ -1279,6 +1275,7 @@ class ScriptView(ContentTypePermissionRequiredMixin, View): return redirect('extras:script_result', job_pk=job.pk) return render(request, 'extras/script.html', { + 'job_count': jobs.count(), 'module': module, 'script': script, 'form': form, @@ -1293,8 +1290,10 @@ class ScriptSourceView(ContentTypePermissionRequiredMixin, View): def get(self, request, module, name): module = get_script_module(module, request) script = module.scripts[name]() + jobs = module.get_jobs(script.class_name) return render(request, 'extras/script/source.html', { + 'job_count': jobs.count(), 'module': module, 'script': script, 'tab': 'source', @@ -1309,13 +1308,7 @@ class ScriptJobsView(ContentTypePermissionRequiredMixin, View): def get(self, request, module, name): module = get_script_module(module, request) script = module.scripts[name]() - - object_type = ContentType.objects.get(app_label='extras', model='scriptmodule') - jobs = Job.objects.filter( - object_type=object_type, - object_id=module.pk, - name=script.class_name - ) + jobs = module.get_jobs(script.class_name) jobs_table = JobTable( data=jobs, @@ -1325,6 +1318,7 @@ class ScriptJobsView(ContentTypePermissionRequiredMixin, View): jobs_table.configure(request) return render(request, 'extras/script/jobs.html', { + 'job_count': jobs.count(), 'module': module, 'script': script, 'table': jobs_table, diff --git a/netbox/templates/extras/report/base.html b/netbox/templates/extras/report/base.html index ff1c6a10f..0bf953ce1 100644 --- a/netbox/templates/extras/report/base.html +++ b/netbox/templates/extras/report/base.html @@ -34,7 +34,7 @@