diff --git a/netbox/dcim/api/serializers_/devicetype_components.py b/netbox/dcim/api/serializers_/devicetype_components.py index 04f6395a6..8d4403d2d 100644 --- a/netbox/dcim/api/serializers_/devicetype_components.py +++ b/netbox/dcim/api/serializers_/devicetype_components.py @@ -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 ) diff --git a/netbox/dcim/forms/bulk_edit.py b/netbox/dcim/forms/bulk_edit.py index 9db7c250e..4cca47782 100644 --- a/netbox/dcim/forms/bulk_edit.py +++ b/netbox/dcim/forms/bulk_edit.py @@ -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() diff --git a/netbox/extras/api/serializers_/configcontexts.py b/netbox/extras/api/serializers_/configcontexts.py index 42a11ffcd..4a3f25e2e 100644 --- a/netbox/extras/api/serializers_/configcontexts.py +++ b/netbox/extras/api/serializers_/configcontexts.py @@ -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, diff --git a/netbox/extras/api/serializers_/configtemplates.py b/netbox/extras/api/serializers_/configtemplates.py index 69652907e..244308535 100644 --- a/netbox/extras/api/serializers_/configtemplates.py +++ b/netbox/extras/api/serializers_/configtemplates.py @@ -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 diff --git a/netbox/extras/api/serializers_/customfields.py b/netbox/extras/api/serializers_/customfields.py index a65fafc4e..f50f7a829 100644 --- a/netbox/extras/api/serializers_/customfields.py +++ b/netbox/extras/api/serializers_/customfields.py @@ -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 diff --git a/netbox/extras/api/serializers_/customlinks.py b/netbox/extras/api/serializers_/customlinks.py index 8cc4f5f77..951c3aded 100644 --- a/netbox/extras/api/serializers_/customlinks.py +++ b/netbox/extras/api/serializers_/customlinks.py @@ -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 diff --git a/netbox/extras/api/serializers_/exporttemplates.py b/netbox/extras/api/serializers_/exporttemplates.py index 0d19d642c..0d3eed442 100644 --- a/netbox/extras/api/serializers_/exporttemplates.py +++ b/netbox/extras/api/serializers_/exporttemplates.py @@ -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 diff --git a/netbox/extras/api/serializers_/notifications.py b/netbox/extras/api/serializers_/notifications.py index 62e1a8d63..9f0c7cff3 100644 --- a/netbox/extras/api/serializers_/notifications.py +++ b/netbox/extras/api/serializers_/notifications.py @@ -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, diff --git a/netbox/extras/api/serializers_/savedfilters.py b/netbox/extras/api/serializers_/savedfilters.py index fb0744e59..e7128389c 100644 --- a/netbox/extras/api/serializers_/savedfilters.py +++ b/netbox/extras/api/serializers_/savedfilters.py @@ -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 diff --git a/netbox/extras/api/serializers_/tags.py b/netbox/extras/api/serializers_/tags.py index 5dc39584f..7567a4543 100644 --- a/netbox/extras/api/serializers_/tags.py +++ b/netbox/extras/api/serializers_/tags.py @@ -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, diff --git a/netbox/extras/forms/bulk_edit.py b/netbox/extras/forms/bulk_edit.py index c854a6c81..1afc8a0f2 100644 --- a/netbox/extras/forms/bulk_edit.py +++ b/netbox/extras/forms/bulk_edit.py @@ -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 diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py index f6fb04072..413b58fe5 100644 --- a/netbox/extras/forms/model_forms.py +++ b/netbox/extras/forms/model_forms.py @@ -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(),