Merge branch 'main' into feature

This commit is contained in:
Jeremy Stretch
2025-08-12 16:03:45 -04:00
103 changed files with 9682 additions and 8351 deletions

View File

@@ -12,6 +12,7 @@ from dcim.choices import *
from dcim.constants import *
from dcim.fields import PathField
from dcim.utils import decompile_path_node, object_to_path_node
from netbox.choices import ColorChoices
from netbox.models import ChangeLoggedModel, PrimaryModel
from utilities.conversion import to_meters
from utilities.exceptions import AbortRequest
@@ -156,6 +157,15 @@ class Cable(PrimaryModel):
self._terminations_modified = True
self._b_terminations = value
@property
def color_name(self):
color_name = ""
for hex_code, label in ColorChoices.CHOICES:
if hex_code.lower() == self.color.lower():
color_name = str(label)
return color_name
def clean(self):
super().clean()

View File

@@ -65,6 +65,29 @@ class ComponentModel(NetBoxModel):
blank=True
)
# Denormalized references replicated from the parent Device
_site = models.ForeignKey(
to='dcim.Site',
on_delete=models.SET_NULL,
related_name='+',
blank=True,
null=True,
)
_location = models.ForeignKey(
to='dcim.Location',
on_delete=models.SET_NULL,
related_name='+',
blank=True,
null=True,
)
_rack = models.ForeignKey(
to='dcim.Rack',
on_delete=models.SET_NULL,
related_name='+',
blank=True,
null=True,
)
class Meta:
abstract = True
ordering = ('device', 'name')
@@ -100,6 +123,14 @@ class ComponentModel(NetBoxModel):
"device": _("Components cannot be moved to a different device.")
})
def save(self, *args, **kwargs):
# Save denormalized references
self._site = self.device.site
self._location = self.device.location
self._rack = self.device.rack
super().save(*args, **kwargs)
@property
def parent_object(self):
return self.device

View File

@@ -9,7 +9,7 @@ from django.core.exceptions import ValidationError
from django.core.files.storage import default_storage
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import F, ProtectedError
from django.db.models import F, ProtectedError, prefetch_related_objects
from django.db.models.functions import Lower
from django.db.models.signals import post_save
from django.urls import reverse
@@ -28,6 +28,7 @@ from netbox.models import NestedGroupModel, OrganizationalModel, PrimaryModel
from netbox.models.mixins import WeightMixin
from netbox.models.features import ContactsMixin, ImageAttachmentsMixin
from utilities.fields import ColorField, CounterCacheField
from utilities.prefetch import get_prefetchable_fields
from utilities.tracking import TrackingModelMixin
from .device_components import *
from .mixins import RenderConfigMixin
@@ -957,7 +958,10 @@ class Device(
if cf_defaults := CustomField.objects.get_defaults_for_model(model):
for component in components:
component.custom_field_data = cf_defaults
model.objects.bulk_create(components)
components = model.objects.bulk_create(components)
# Prefetch related objects to minimize queries needed during post_save
prefetch_fields = get_prefetchable_fields(model)
prefetch_related_objects(components, *prefetch_fields)
# Manually send the post_save signal for each of the newly created components
for component in components:
post_save.send(
@@ -1305,7 +1309,7 @@ class MACAddress(PrimaryModel):
)
class Meta:
ordering = ('mac_address',)
ordering = ('mac_address', 'pk',)
verbose_name = _('MAC address')
verbose_name_plural = _('MAC addresses')