1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Closes #5901: Add 'created' and 'last_updated' fields to device component models

This commit is contained in:
Jeremy Stretch
2021-03-01 15:42:39 -05:00
parent 1ddc1a6781
commit 07e6abdac4
7 changed files with 210 additions and 19 deletions

View File

@ -9,6 +9,7 @@
* [#5370](https://github.com/netbox-community/netbox/issues/5370) - Extend custom field support to organizational models
* [#5401](https://github.com/netbox-community/netbox/issues/5401) - Extend custom field support to device component models
* [#5451](https://github.com/netbox-community/netbox/issues/5451) - Add support for multiple-selection custom fields
* [#5901](https://github.com/netbox-community/netbox/issues/5901) - Add `created` and `last_updated` fields to device component models
### Other Changes

View File

@ -288,7 +288,7 @@ class ConsolePortTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = ConsolePortTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'description']
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'description', 'created', 'last_updated']
class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
@ -302,7 +302,7 @@ class ConsoleServerPortTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = ConsoleServerPortTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'description']
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'description', 'created', 'last_updated']
class PowerPortTemplateSerializer(ValidatedModelSerializer):
@ -316,7 +316,10 @@ class PowerPortTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = PowerPortTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description']
fields = [
'id', 'url', 'device_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description',
'created', 'last_updated',
]
class PowerOutletTemplateSerializer(ValidatedModelSerializer):
@ -338,7 +341,10 @@ class PowerOutletTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = PowerOutletTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description']
fields = [
'id', 'url', 'device_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'created',
'last_updated',
]
class InterfaceTemplateSerializer(ValidatedModelSerializer):
@ -348,7 +354,9 @@ class InterfaceTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = InterfaceTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'mgmt_only', 'description']
fields = [
'id', 'url', 'device_type', 'name', 'label', 'type', 'mgmt_only', 'description', 'created', 'last_updated',
]
class RearPortTemplateSerializer(ValidatedModelSerializer):
@ -358,7 +366,9 @@ class RearPortTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = RearPortTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'positions', 'description']
fields = [
'id', 'url', 'device_type', 'name', 'label', 'type', 'positions', 'description', 'created', 'last_updated',
]
class FrontPortTemplateSerializer(ValidatedModelSerializer):
@ -369,7 +379,10 @@ class FrontPortTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = FrontPortTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description']
fields = [
'id', 'url', 'device_type', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description',
'created', 'last_updated',
]
class DeviceBayTemplateSerializer(ValidatedModelSerializer):
@ -378,7 +391,7 @@ class DeviceBayTemplateSerializer(ValidatedModelSerializer):
class Meta:
model = DeviceBayTemplate
fields = ['id', 'url', 'device_type', 'name', 'label', 'description']
fields = ['id', 'url', 'device_type', 'name', 'label', 'description', 'created', 'last_updated']
#
@ -498,6 +511,7 @@ class ConsoleServerPortSerializer(TaggedObjectSerializer, CableTerminationSerial
fields = [
'id', 'url', 'device', 'name', 'label', 'type', 'description', 'cable', 'cable_peer', 'cable_peer_type',
'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields',
'created', 'last_updated',
]
@ -516,6 +530,7 @@ class ConsolePortSerializer(TaggedObjectSerializer, CableTerminationSerializer,
fields = [
'id', 'url', 'device', 'name', 'label', 'type', 'description', 'cable', 'cable_peer', 'cable_peer_type',
'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields',
'created', 'last_updated',
]
@ -544,7 +559,7 @@ class PowerOutletSerializer(TaggedObjectSerializer, CableTerminationSerializer,
fields = [
'id', 'url', 'device', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description', 'cable',
'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated',
]
@ -563,7 +578,7 @@ class PowerPortSerializer(TaggedObjectSerializer, CableTerminationSerializer, Co
fields = [
'id', 'url', 'device', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description', 'cable',
'cable_peer', 'cable_peer_type', 'connected_endpoint', 'connected_endpoint_type',
'connected_endpoint_reachable', 'tags', 'custom_fields',
'connected_endpoint_reachable', 'tags', 'custom_fields', 'created', 'last_updated',
]
@ -589,7 +604,7 @@ class InterfaceSerializer(TaggedObjectSerializer, CableTerminationSerializer, Co
'id', 'url', 'device', 'name', 'label', 'type', 'enabled', 'lag', 'mtu', 'mac_address', 'mgmt_only',
'description', 'mode', 'untagged_vlan', 'tagged_vlans', 'cable', 'cable_peer', 'cable_peer_type',
'connected_endpoint', 'connected_endpoint_type', 'connected_endpoint_reachable', 'tags', 'custom_fields',
'count_ipaddresses',
'created', 'last_updated', 'count_ipaddresses',
]
def validate(self, data):
@ -616,7 +631,7 @@ class RearPortSerializer(TaggedObjectSerializer, CableTerminationSerializer, Cus
model = RearPort
fields = [
'id', 'url', 'device', 'name', 'label', 'type', 'positions', 'description', 'cable', 'cable_peer',
'cable_peer_type', 'tags', 'custom_fields',
'cable_peer_type', 'tags', 'custom_fields', 'created', 'last_updated',
]
@ -642,7 +657,7 @@ class FrontPortSerializer(TaggedObjectSerializer, CableTerminationSerializer, Cu
model = FrontPort
fields = [
'id', 'url', 'device', 'name', 'label', 'type', 'rear_port', 'rear_port_position', 'description', 'cable',
'cable_peer', 'cable_peer_type', 'tags', 'custom_fields',
'cable_peer', 'cable_peer_type', 'tags', 'custom_fields', 'created', 'last_updated',
]
@ -653,7 +668,10 @@ class DeviceBaySerializer(TaggedObjectSerializer, CustomFieldModelSerializer):
class Meta:
model = DeviceBay
fields = ['id', 'url', 'device', 'name', 'label', 'description', 'installed_device', 'tags', 'custom_fields']
fields = [
'id', 'url', 'device', 'name', 'label', 'description', 'installed_device', 'tags', 'custom_fields',
'created', 'last_updated',
]
#
@ -672,7 +690,7 @@ class InventoryItemSerializer(TaggedObjectSerializer, CustomFieldModelSerializer
model = InventoryItem
fields = [
'id', 'url', 'device', 'parent', 'name', 'label', 'manufacturer', 'part_id', 'serial', 'asset_tag',
'discovered', 'description', 'tags', 'custom_fields', '_depth',
'discovered', 'description', 'tags', 'custom_fields', 'created', 'last_updated', '_depth',
]

View File

@ -9,41 +9,151 @@ class Migration(migrations.Migration):
]
operations = [
migrations.AddField(
model_name='consoleport',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='consoleport',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='consoleport',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='consoleporttemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='consoleporttemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='consoleserverport',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='consoleserverport',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='consoleserverport',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='consoleserverporttemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='consoleserverporttemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='devicebay',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='devicebay',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='devicebay',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='devicebaytemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='devicebaytemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='devicerole',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='frontport',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='frontport',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='frontport',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='frontporttemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='frontporttemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='interface',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='interface',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='interface',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='interfacetemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='interfacetemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='inventoryitem',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='inventoryitem',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='inventoryitem',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='manufacturer',
name='custom_field_data',
@ -54,16 +164,56 @@ class Migration(migrations.Migration):
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='poweroutlet',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='poweroutlet',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='poweroutlet',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='poweroutlettemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='poweroutlettemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='powerport',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='powerport',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='powerport',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='powerporttemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='powerporttemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='rackgroup',
name='custom_field_data',
@ -74,11 +224,31 @@ class Migration(migrations.Migration):
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='rearport',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='rearport',
name='custom_field_data',
field=models.JSONField(blank=True, default=dict, encoder=django.core.serializers.json.DjangoJSONEncoder),
),
migrations.AddField(
model_name='rearport',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='rearporttemplate',
name='created',
field=models.DateField(auto_now_add=True, null=True),
),
migrations.AddField(
model_name='rearporttemplate',
name='last_updated',
field=models.DateTimeField(auto_now=True, null=True),
),
migrations.AddField(
model_name='region',
name='custom_field_data',

View File

@ -6,7 +6,7 @@ from dcim.choices import *
from dcim.constants import *
from extras.models import ObjectChange
from extras.utils import extras_features
from netbox.models import BigIDModel
from netbox.models import BigIDModel, ChangeLoggingMixin
from utilities.fields import NaturalOrderingField
from utilities.querysets import RestrictedQuerySet
from utilities.ordering import naturalize_interface
@ -28,7 +28,7 @@ __all__ = (
)
class ComponentTemplateModel(BigIDModel):
class ComponentTemplateModel(ChangeLoggingMixin, BigIDModel):
device_type = models.ForeignKey(
to='dcim.DeviceType',
on_delete=models.CASCADE,

View File

@ -13,7 +13,7 @@ from dcim.constants import *
from dcim.fields import MACAddressField
from extras.models import ObjectChange, TaggedItem
from extras.utils import extras_features
from netbox.models import BigIDModel, CustomFieldsMixin
from netbox.models import PrimaryModel
from utilities.fields import NaturalOrderingField
from utilities.mptt import TreeManager
from utilities.ordering import naturalize_interface
@ -38,7 +38,7 @@ __all__ = (
)
class ComponentModel(CustomFieldsMixin, BigIDModel):
class ComponentModel(PrimaryModel):
"""
An abstract model inherited by any model which has a parent Device.
"""

View File

@ -10,6 +10,7 @@ from utilities.utils import serialize_object
__all__ = (
'BigIDModel',
'ChangeLoggingMixin',
'CustomFieldsMixin',
'NestedGroupModel',
'OrganizationalModel',

View File

@ -30,6 +30,7 @@
{% endif %}
</div>
<h1>{% block title %}{{ object.device }} / {{ object }}{% endblock %}</h1>
{% include 'inc/created_updated.html' %}
<ul class="nav nav-tabs">
<li role="presentation"{% if not active_tab %} class="active"{% endif %}>
<a href="{{ object.get_absolute_url }}">{{ object|meta:"verbose_name"|bettertitle }}</a>