From 87ff83ef1fb689c6dcb57b29ca2d76d3797bfab5 Mon Sep 17 00:00:00 2001 From: Martin Hauser Date: Tue, 4 Nov 2025 22:58:54 +0100 Subject: [PATCH] feat(filtersets): Add `object_type_id` filter for Jobs (#20674) Introduce a new `object_type_id` filter to enhance filtering by object type for Jobs. Update related forms and fieldsets to incorporate the new filter for better usability and consistency. Fixes #20653 --- netbox/core/api/serializers_/jobs.py | 26 ++++++++++++++++++++++++-- netbox/core/filtersets.py | 6 +++++- netbox/core/forms/filtersets.py | 4 ++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/netbox/core/api/serializers_/jobs.py b/netbox/core/api/serializers_/jobs.py index dd0dd1245..26726ebdd 100644 --- a/netbox/core/api/serializers_/jobs.py +++ b/netbox/core/api/serializers_/jobs.py @@ -1,8 +1,13 @@ +from drf_spectacular.utils import extend_schema_field +from rest_framework import serializers + from core.choices import * from core.models import Job +from netbox.api.exceptions import SerializerNotFound from netbox.api.fields import ChoiceField, ContentTypeField from netbox.api.serializers import BaseModelSerializer from users.api.serializers_.users import UserSerializer +from utilities.api import get_serializer_for_model __all__ = ( 'JobSerializer', @@ -18,11 +23,28 @@ class JobSerializer(BaseModelSerializer): object_type = ContentTypeField( read_only=True ) + object = serializers.SerializerMethodField( + read_only=True + ) class Meta: model = Job fields = [ - 'id', 'url', 'display_url', 'display', 'object_type', 'object_id', 'name', 'status', 'created', 'scheduled', - 'interval', 'started', 'completed', 'user', 'data', 'error', 'job_id', 'log_entries', + 'id', 'url', 'display_url', 'display', 'object_type', 'object_id', 'object', 'name', 'status', 'created', + 'scheduled', 'interval', 'started', 'completed', 'user', 'data', 'error', 'job_id', 'log_entries', ] brief_fields = ('url', 'created', 'completed', 'user', 'status') + + @extend_schema_field(serializers.JSONField(allow_null=True)) + def get_object(self, obj): + """ + Serialize a nested representation of the object. + """ + if obj.object is None: + return None + try: + serializer = get_serializer_for_model(obj.object) + except SerializerNotFound: + return obj.object_repr + context = {'request': self.context['request']} + return serializer(obj.object, nested=True, context=context).data diff --git a/netbox/core/filtersets.py b/netbox/core/filtersets.py index 391ac02f7..2454e0b86 100644 --- a/netbox/core/filtersets.py +++ b/netbox/core/filtersets.py @@ -80,6 +80,10 @@ class JobFilterSet(BaseFilterSet): method='search', label=_('Search'), ) + object_type_id = django_filters.ModelMultipleChoiceFilter( + queryset=ObjectType.objects.with_feature('jobs'), + field_name='object_type_id', + ) object_type = ContentTypeFilter() created = django_filters.DateTimeFilter() created__before = django_filters.DateTimeFilter( @@ -124,7 +128,7 @@ class JobFilterSet(BaseFilterSet): class Meta: model = Job - fields = ('id', 'object_type', 'object_id', 'name', 'interval', 'status', 'user', 'job_id') + fields = ('id', 'object_type', 'object_type_id', 'object_id', 'name', 'interval', 'status', 'user', 'job_id') def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/core/forms/filtersets.py b/netbox/core/forms/filtersets.py index 0f25932e0..f9310a70c 100644 --- a/netbox/core/forms/filtersets.py +++ b/netbox/core/forms/filtersets.py @@ -70,13 +70,13 @@ class JobFilterForm(SavedFiltersMixin, FilterForm): model = Job fieldsets = ( FieldSet('q', 'filter_id'), - FieldSet('object_type', 'status', name=_('Attributes')), + FieldSet('object_type_id', 'status', name=_('Attributes')), FieldSet( 'created__before', 'created__after', 'scheduled__before', 'scheduled__after', 'started__before', 'started__after', 'completed__before', 'completed__after', 'user', name=_('Creation') ), ) - object_type = ContentTypeChoiceField( + object_type_id = ContentTypeChoiceField( label=_('Object Type'), queryset=ObjectType.objects.with_feature('jobs'), required=False,