Add missing mixins for changelog message support

This commit is contained in:
Jeremy Stretch 2025-07-25 14:22:04 -04:00
parent 3fba47eb08
commit 5bed9e8667
12 changed files with 60 additions and 50 deletions

View File

@ -9,7 +9,7 @@ from dcim.models import (
InventoryItemTemplate, ModuleBayTemplate, PowerOutletTemplate, PowerPortTemplate, RearPortTemplate,
)
from netbox.api.fields import ChoiceField, ContentTypeField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
from utilities.api import get_serializer_for_model
from wireless.choices import *
from .devicetypes import DeviceTypeSerializer, ModuleTypeSerializer
@ -31,7 +31,11 @@ __all__ = (
)
class ConsolePortTemplateSerializer(ValidatedModelSerializer):
class ComponentTemplateSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
pass
class ConsolePortTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -59,7 +63,7 @@ class ConsolePortTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
class ConsoleServerPortTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -87,7 +91,7 @@ class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class PowerPortTemplateSerializer(ValidatedModelSerializer):
class PowerPortTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -116,7 +120,7 @@ class PowerPortTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class PowerOutletTemplateSerializer(ValidatedModelSerializer):
class PowerOutletTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -156,7 +160,7 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class InterfaceTemplateSerializer(ValidatedModelSerializer):
class InterfaceTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -202,7 +206,7 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class RearPortTemplateSerializer(ValidatedModelSerializer):
class RearPortTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
required=False,
nested=True,
@ -226,7 +230,7 @@ class RearPortTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class FrontPortTemplateSerializer(ValidatedModelSerializer):
class FrontPortTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -251,7 +255,7 @@ class FrontPortTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class ModuleBayTemplateSerializer(ValidatedModelSerializer):
class ModuleBayTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True,
required=False,
@ -274,7 +278,7 @@ class ModuleBayTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class DeviceBayTemplateSerializer(ValidatedModelSerializer):
class DeviceBayTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True
)
@ -288,7 +292,7 @@ class DeviceBayTemplateSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description')
class InventoryItemTemplateSerializer(ValidatedModelSerializer):
class InventoryItemTemplateSerializer(ComponentTemplateSerializer):
device_type = DeviceTypeSerializer(
nested=True
)

View File

@ -11,6 +11,7 @@ from ipam.choices import VLANQinQRoleChoices
from ipam.models import ASN, VLAN, VLANGroup, VRF
from netbox.choices import *
from netbox.forms import NetBoxModelBulkEditForm
from netbox.forms.mixins import ChangeLoggingMixin
from tenancy.models import Tenant
from users.models import User
from utilities.forms import BulkEditForm, add_blank_choice, form_from_model
@ -1037,7 +1038,11 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
# Device component templates
#
class ConsolePortTemplateBulkEditForm(BulkEditForm):
class ComponentTemplateBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pass
class ConsolePortTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=ConsolePortTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1056,7 +1061,7 @@ class ConsolePortTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('label', 'type', 'description')
class ConsoleServerPortTemplateBulkEditForm(BulkEditForm):
class ConsoleServerPortTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=ConsoleServerPortTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1079,7 +1084,7 @@ class ConsoleServerPortTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('label', 'type', 'description')
class PowerPortTemplateBulkEditForm(BulkEditForm):
class PowerPortTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=PowerPortTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1114,7 +1119,7 @@ class PowerPortTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('label', 'type', 'maximum_draw', 'allocated_draw', 'description')
class PowerOutletTemplateBulkEditForm(BulkEditForm):
class PowerOutletTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=PowerOutletTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1165,7 +1170,7 @@ class PowerOutletTemplateBulkEditForm(BulkEditForm):
self.fields['power_port'].widget.attrs['disabled'] = True
class InterfaceTemplateBulkEditForm(BulkEditForm):
class InterfaceTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=InterfaceTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1216,7 +1221,7 @@ class InterfaceTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('label', 'description', 'poe_mode', 'poe_type', 'rf_role')
class FrontPortTemplateBulkEditForm(BulkEditForm):
class FrontPortTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=FrontPortTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1243,7 +1248,7 @@ class FrontPortTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('description',)
class RearPortTemplateBulkEditForm(BulkEditForm):
class RearPortTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=RearPortTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1270,7 +1275,7 @@ class RearPortTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('description',)
class ModuleBayTemplateBulkEditForm(BulkEditForm):
class ModuleBayTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=ModuleBayTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1288,7 +1293,7 @@ class ModuleBayTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('label', 'position', 'description')
class DeviceBayTemplateBulkEditForm(BulkEditForm):
class DeviceBayTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=DeviceBayTemplate.objects.all(),
widget=forms.MultipleHiddenInput()
@ -1306,7 +1311,7 @@ class DeviceBayTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('label', 'description')
class InventoryItemTemplateBulkEditForm(BulkEditForm):
class InventoryItemTemplateBulkEditForm(ComponentTemplateBulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=InventoryItemTemplate.objects.all(),
widget=forms.MultipleHiddenInput()

View File

@ -8,7 +8,7 @@ from dcim.api.serializers_.sites import LocationSerializer, RegionSerializer, Si
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
from extras.models import ConfigContext, Tag
from netbox.api.fields import SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
from tenancy.api.serializers_.tenants import TenantSerializer, TenantGroupSerializer
from tenancy.models import Tenant, TenantGroup
from virtualization.api.serializers_.clusters import ClusterSerializer, ClusterGroupSerializer, ClusterTypeSerializer
@ -19,7 +19,7 @@ __all__ = (
)
class ConfigContextSerializer(ValidatedModelSerializer):
class ConfigContextSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
regions = SerializedPKRelatedField(
queryset=Region.objects.all(),
serializer=RegionSerializer,

View File

@ -1,6 +1,6 @@
from core.api.serializers_.data import DataFileSerializer, DataSourceSerializer
from extras.models import ConfigTemplate
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
from netbox.api.serializers.features import TaggableModelSerializer
__all__ = (
@ -8,7 +8,7 @@ __all__ = (
)
class ConfigTemplateSerializer(TaggableModelSerializer, ValidatedModelSerializer):
class ConfigTemplateSerializer(ChangeLogMessageSerializer, TaggableModelSerializer, ValidatedModelSerializer):
data_source = DataSourceSerializer(
nested=True,
required=False

View File

@ -7,7 +7,7 @@ from core.models import ObjectType
from extras.choices import *
from extras.models import CustomField, CustomFieldChoiceSet
from netbox.api.fields import ChoiceField, ContentTypeField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
__all__ = (
'CustomFieldChoiceSetSerializer',
@ -15,7 +15,7 @@ __all__ = (
)
class CustomFieldChoiceSetSerializer(ValidatedModelSerializer):
class CustomFieldChoiceSetSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
base_choices = ChoiceField(
choices=CustomFieldChoiceSetBaseChoices,
required=False
@ -36,7 +36,7 @@ class CustomFieldChoiceSetSerializer(ValidatedModelSerializer):
brief_fields = ('id', 'url', 'display', 'name', 'description', 'choices_count')
class CustomFieldSerializer(ValidatedModelSerializer):
class CustomFieldSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
object_types = ContentTypeField(
queryset=ObjectType.objects.with_feature('custom_fields'),
many=True

View File

@ -1,14 +1,14 @@
from core.models import ObjectType
from extras.models import CustomLink
from netbox.api.fields import ContentTypeField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
__all__ = (
'CustomLinkSerializer',
)
class CustomLinkSerializer(ValidatedModelSerializer):
class CustomLinkSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
object_types = ContentTypeField(
queryset=ObjectType.objects.with_feature('custom_links'),
many=True

View File

@ -2,14 +2,14 @@ from core.api.serializers_.data import DataFileSerializer, DataSourceSerializer
from core.models import ObjectType
from extras.models import ExportTemplate
from netbox.api.fields import ContentTypeField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
__all__ = (
'ExportTemplateSerializer',
)
class ExportTemplateSerializer(ValidatedModelSerializer):
class ExportTemplateSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
object_types = ContentTypeField(
queryset=ObjectType.objects.with_feature('export_templates'),
many=True

View File

@ -4,7 +4,7 @@ from rest_framework import serializers
from core.models import ObjectType
from extras.models import Notification, NotificationGroup, Subscription
from netbox.api.fields import ContentTypeField, SerializedPKRelatedField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
from users.api.serializers_.users import GroupSerializer, UserSerializer
from users.models import Group, User
from utilities.api import get_serializer_for_model
@ -37,7 +37,7 @@ class NotificationSerializer(ValidatedModelSerializer):
return serializer(instance.object, nested=True, context=context).data
class NotificationGroupSerializer(ValidatedModelSerializer):
class NotificationGroupSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
groups = SerializedPKRelatedField(
queryset=Group.objects.all(),
serializer=GroupSerializer,

View File

@ -1,14 +1,14 @@
from core.models import ObjectType
from extras.models import SavedFilter
from netbox.api.fields import ContentTypeField
from netbox.api.serializers import ValidatedModelSerializer
from netbox.api.serializers import ChangeLogMessageSerializer, ValidatedModelSerializer
__all__ = (
'SavedFilterSerializer',
)
class SavedFilterSerializer(ValidatedModelSerializer):
class SavedFilterSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
object_types = ContentTypeField(
queryset=ObjectType.objects.all(),
many=True

View File

@ -5,7 +5,7 @@ from core.models import ObjectType
from extras.models import Tag, TaggedItem
from netbox.api.exceptions import SerializerNotFound
from netbox.api.fields import ContentTypeField, RelatedObjectCountField
from netbox.api.serializers import BaseModelSerializer, ValidatedModelSerializer
from netbox.api.serializers import BaseModelSerializer, ChangeLogMessageSerializer, ValidatedModelSerializer
from utilities.api import get_serializer_for_model
__all__ = (
@ -14,7 +14,7 @@ __all__ = (
)
class TagSerializer(ValidatedModelSerializer):
class TagSerializer(ChangeLogMessageSerializer, ValidatedModelSerializer):
object_types = ContentTypeField(
queryset=ObjectType.objects.with_feature('tags'),
many=True,

View File

@ -5,6 +5,7 @@ from extras.choices import *
from extras.models import *
from netbox.events import get_event_type_choices
from netbox.forms import NetBoxModelBulkEditForm
from netbox.forms.mixins import ChangeLoggingMixin
from utilities.forms import BulkEditForm, add_blank_choice
from utilities.forms.fields import ColorField, CommentField, DynamicModelChoiceField
from utilities.forms.rendering import FieldSet
@ -27,7 +28,7 @@ __all__ = (
)
class CustomFieldBulkEditForm(BulkEditForm):
class CustomFieldBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=CustomField.objects.all(),
widget=forms.MultipleHiddenInput
@ -95,7 +96,7 @@ class CustomFieldBulkEditForm(BulkEditForm):
nullable_fields = ('group_name', 'description', 'choice_set')
class CustomFieldChoiceSetBulkEditForm(BulkEditForm):
class CustomFieldChoiceSetBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=CustomFieldChoiceSet.objects.all(),
widget=forms.MultipleHiddenInput
@ -115,7 +116,7 @@ class CustomFieldChoiceSetBulkEditForm(BulkEditForm):
nullable_fields = ('base_choices', 'description')
class CustomLinkBulkEditForm(BulkEditForm):
class CustomLinkBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=CustomLink.objects.all(),
widget=forms.MultipleHiddenInput
@ -141,7 +142,7 @@ class CustomLinkBulkEditForm(BulkEditForm):
)
class ExportTemplateBulkEditForm(BulkEditForm):
class ExportTemplateBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=ExportTemplate.objects.all(),
widget=forms.MultipleHiddenInput
@ -174,7 +175,7 @@ class ExportTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('description', 'mime_type', 'file_name', 'file_extension')
class SavedFilterBulkEditForm(BulkEditForm):
class SavedFilterBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=SavedFilter.objects.all(),
widget=forms.MultipleHiddenInput
@ -294,7 +295,7 @@ class EventRuleBulkEditForm(NetBoxModelBulkEditForm):
nullable_fields = ('description', 'conditions')
class TagBulkEditForm(BulkEditForm):
class TagBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=Tag.objects.all(),
widget=forms.MultipleHiddenInput
@ -316,7 +317,7 @@ class TagBulkEditForm(BulkEditForm):
nullable_fields = ('description',)
class ConfigContextBulkEditForm(BulkEditForm):
class ConfigContextBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=ConfigContext.objects.all(),
widget=forms.MultipleHiddenInput
@ -340,7 +341,7 @@ class ConfigContextBulkEditForm(BulkEditForm):
nullable_fields = ('description',)
class ConfigTemplateBulkEditForm(BulkEditForm):
class ConfigTemplateBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=ConfigTemplate.objects.all(),
widget=forms.MultipleHiddenInput
@ -373,7 +374,7 @@ class ConfigTemplateBulkEditForm(BulkEditForm):
nullable_fields = ('description', 'mime_type', 'file_name', 'file_extension')
class JournalEntryBulkEditForm(BulkEditForm):
class JournalEntryBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=JournalEntry.objects.all(),
widget=forms.MultipleHiddenInput
@ -386,7 +387,7 @@ class JournalEntryBulkEditForm(BulkEditForm):
comments = CommentField()
class NotificationGroupBulkEditForm(BulkEditForm):
class NotificationGroupBulkEditForm(ChangeLoggingMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField(
queryset=NotificationGroup.objects.all(),
widget=forms.MultipleHiddenInput

View File

@ -585,7 +585,7 @@ class TagForm(ChangeLoggingMixin, forms.ModelForm):
]
class ConfigContextForm(SyncedDataMixin, forms.ModelForm):
class ConfigContextForm(ChangeLoggingMixin, SyncedDataMixin, forms.ModelForm):
regions = DynamicModelMultipleChoiceField(
label=_('Regions'),
queryset=Region.objects.all(),
@ -697,7 +697,7 @@ class ConfigContextForm(SyncedDataMixin, forms.ModelForm):
return self.cleaned_data
class ConfigTemplateForm(SyncedDataMixin, forms.ModelForm):
class ConfigTemplateForm(ChangeLoggingMixin, SyncedDataMixin, forms.ModelForm):
tags = DynamicModelMultipleChoiceField(
label=_('Tags'),
queryset=Tag.objects.all(),