mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-26 17:26:10 -06:00
Introduce get_latest_jobs() method on JobsMixin
This commit is contained in:
parent
c915d2360c
commit
556353c2f3
@ -39,7 +39,8 @@ class Job(models.Model):
|
|||||||
)
|
)
|
||||||
object = GenericForeignKey(
|
object = GenericForeignKey(
|
||||||
ct_field='object_type',
|
ct_field='object_type',
|
||||||
fk_field='object_id'
|
fk_field='object_id',
|
||||||
|
for_concrete_model=False
|
||||||
)
|
)
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=200
|
max_length=200
|
||||||
|
@ -819,18 +819,9 @@ class ReportListView(ContentTypePermissionRequiredMixin, View):
|
|||||||
def get(self, request):
|
def get(self, request):
|
||||||
report_modules = ReportModule.objects.restrict(request.user)
|
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', {
|
return render(request, 'extras/report_list.html', {
|
||||||
'model': ReportModule,
|
'model': ReportModule,
|
||||||
'report_modules': report_modules,
|
'report_modules': report_modules,
|
||||||
'jobs': jobs,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -986,18 +977,9 @@ class ScriptListView(ContentTypePermissionRequiredMixin, View):
|
|||||||
def get(self, request):
|
def get(self, request):
|
||||||
script_modules = ScriptModule.objects.restrict(request.user)
|
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', {
|
return render(request, 'extras/script_list.html', {
|
||||||
'model': ScriptModule,
|
'model': ScriptModule,
|
||||||
'script_modules': script_modules,
|
'script_modules': script_modules,
|
||||||
'jobs': jobs,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@ from django.db.models.signals import class_prepared
|
|||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
|
|
||||||
from taggit.managers import TaggableManager
|
from taggit.managers import TaggableManager
|
||||||
|
|
||||||
|
from core.choices import JobStatusChoices
|
||||||
from extras.choices import CustomFieldVisibilityChoices, ObjectChangeActionChoices
|
from extras.choices import CustomFieldVisibilityChoices, ObjectChangeActionChoices
|
||||||
from extras.utils import is_taggable, register_features
|
from extras.utils import is_taggable, register_features
|
||||||
from netbox.registry import registry
|
from netbox.registry import registry
|
||||||
@ -302,12 +302,24 @@ class JobsMixin(models.Model):
|
|||||||
jobs = GenericRelation(
|
jobs = GenericRelation(
|
||||||
to='core.Job',
|
to='core.Job',
|
||||||
content_type_field='object_type',
|
content_type_field='object_type',
|
||||||
object_id_field='object_id'
|
object_id_field='object_id',
|
||||||
|
for_concrete_model=False
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
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):
|
class JournalingMixin(models.Model):
|
||||||
"""
|
"""
|
||||||
|
@ -49,56 +49,58 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for report_name, report in module.reports.items %}
|
{% with jobs=module.get_latest_jobs %}
|
||||||
{% with last_result=jobs|get_key:report.name %}
|
{% for report_name, report in module.reports.items %}
|
||||||
<tr>
|
{% with last_job=jobs|get_key:report.name %}
|
||||||
<td>
|
|
||||||
<a href="{% url 'extras:report' module=module.path name=report.class_name %}" id="{{ report.module }}.{{ report.class_name }}">{{ report.name }}</a>
|
|
||||||
</td>
|
|
||||||
<td>{{ report.description|markdown|placeholder }}</td>
|
|
||||||
{% if last_result %}
|
|
||||||
<td>
|
|
||||||
<a href="{% url 'extras:report_result' job_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% badge last_result.get_status_display last_result.get_status_color %}
|
|
||||||
</td>
|
|
||||||
{% else %}
|
|
||||||
<td class="text-muted">Never</td>
|
|
||||||
<td>{{ ''|placeholder }}</td>
|
|
||||||
{% endif %}
|
|
||||||
<td>
|
|
||||||
{% if perms.extras.run_report %}
|
|
||||||
<div class="float-end noprint">
|
|
||||||
<form action="{% url 'extras:report' module=report.module name=report.class_name %}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<button type="submit" name="_run" class="btn btn-primary btn-sm" style="width: 110px">
|
|
||||||
{% if last_result %}
|
|
||||||
<i class="mdi mdi-replay"></i> Run Again
|
|
||||||
{% else %}
|
|
||||||
<i class="mdi mdi-play"></i> Run Report
|
|
||||||
{% endif %}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{% for method, stats in last_result.data.items %}
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="4" class="method">
|
<td>
|
||||||
<span class="ps-3">{{ method }}</span>
|
<a href="{% url 'extras:report' module=module.path name=report.class_name %}" id="{{ report.module }}.{{ report.class_name }}">{{ report.name }}</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="text-end text-nowrap report-stats">
|
<td>{{ report.description|markdown|placeholder }}</td>
|
||||||
<span class="badge bg-success">{{ stats.success }}</span>
|
{% if last_job %}
|
||||||
<span class="badge bg-info">{{ stats.info }}</span>
|
<td>
|
||||||
<span class="badge bg-warning">{{ stats.warning }}</span>
|
<a href="{% url 'extras:report_result' job_pk=last_job.pk %}">{{ last_job.created|annotated_date }}</a>
|
||||||
<span class="badge bg-danger">{{ stats.failure }}</span>
|
</td>
|
||||||
|
<td>
|
||||||
|
{% badge last_job.get_status_display last_job.get_status_color %}
|
||||||
|
</td>
|
||||||
|
{% else %}
|
||||||
|
<td class="text-muted">Never</td>
|
||||||
|
<td>{{ ''|placeholder }}</td>
|
||||||
|
{% endif %}
|
||||||
|
<td>
|
||||||
|
{% if perms.extras.run_report %}
|
||||||
|
<div class="float-end noprint">
|
||||||
|
<form action="{% url 'extras:report' module=report.module name=report.class_name %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<button type="submit" name="_run" class="btn btn-primary btn-sm" style="width: 110px">
|
||||||
|
{% if last_job %}
|
||||||
|
<i class="mdi mdi-replay"></i> Run Again
|
||||||
|
{% else %}
|
||||||
|
<i class="mdi mdi-play"></i> Run Report
|
||||||
|
{% endif %}
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% for method, stats in last_job.data.items %}
|
||||||
{% endwith %}
|
<tr>
|
||||||
{% endfor %}
|
<td colspan="4" class="method">
|
||||||
|
<span class="ps-3">{{ method }}</span>
|
||||||
|
</td>
|
||||||
|
<td class="text-end text-nowrap report-stats">
|
||||||
|
<span class="badge bg-success">{{ stats.success }}</span>
|
||||||
|
<span class="badge bg-info">{{ stats.info }}</span>
|
||||||
|
<span class="badge bg-warning">{{ stats.warning }}</span>
|
||||||
|
<span class="badge bg-danger">{{ stats.failure }}</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endwith %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for script_name, script_class in module.scripts.items %}
|
{% with jobs=module.get_latest_jobs %}
|
||||||
{% with last_result=jobs|get_key:script_class.name %}
|
{% for script_name, script_class in module.scripts.items %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<a href="{% url 'extras:script' module=module.path name=script_name %}" name="script.{{ script_name }}">{{ script_class.name }}</a>
|
<a href="{% url 'extras:script' module=module.path name=script_name %}" name="script.{{ script_name }}">{{ script_class.name }}</a>
|
||||||
@ -56,20 +56,22 @@
|
|||||||
<td>
|
<td>
|
||||||
{{ script_class.Meta.description|markdown|placeholder }}
|
{{ script_class.Meta.description|markdown|placeholder }}
|
||||||
</td>
|
</td>
|
||||||
{% if last_result %}
|
{% with last_result=jobs|get_key:script_class.name %}
|
||||||
<td>
|
{% if last_result %}
|
||||||
<a href="{% url 'extras:script_result' job_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
<td>
|
||||||
</td>
|
<a href="{% url 'extras:script_result' job_pk=last_result.pk %}">{{ last_result.created|annotated_date }}</a>
|
||||||
<td class="text-end">
|
</td>
|
||||||
{% badge last_result.get_status_display last_result.get_status_color %}
|
<td class="text-end">
|
||||||
</td>
|
{% badge last_result.get_status_display last_result.get_status_color %}
|
||||||
{% else %}
|
</td>
|
||||||
<td class="text-muted">Never</td>
|
{% else %}
|
||||||
<td class="text-end">{{ ''|placeholder }}</td>
|
<td class="text-muted">Never</td>
|
||||||
{% endif %}
|
<td class="text-end">{{ ''|placeholder }}</td>
|
||||||
|
{% endif %}
|
||||||
|
{% endwith %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endwith %}
|
{% endfor %}
|
||||||
{% endfor %}
|
{% endwith %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user