mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #5895: Rename RackGroup to Location
This commit is contained in:
@@ -16,21 +16,20 @@ from taggit.managers import TaggableManager
|
||||
from dcim.choices import *
|
||||
from dcim.constants import *
|
||||
from dcim.elevations import RackElevationSVG
|
||||
from extras.models import ObjectChange, TaggedItem
|
||||
from extras.models import TaggedItem
|
||||
from extras.utils import extras_features
|
||||
from netbox.models import NestedGroupModel, OrganizationalModel, PrimaryModel
|
||||
from utilities.choices import ColorChoices
|
||||
from utilities.fields import ColorField, NaturalOrderingField
|
||||
from utilities.querysets import RestrictedQuerySet
|
||||
from utilities.mptt import TreeManager
|
||||
from utilities.utils import array_to_string, serialize_object
|
||||
from utilities.utils import array_to_string
|
||||
from .device_components import PowerOutlet, PowerPort
|
||||
from .devices import Device
|
||||
from .power import PowerFeed
|
||||
|
||||
__all__ = (
|
||||
'Rack',
|
||||
'RackGroup',
|
||||
'Location',
|
||||
'RackReservation',
|
||||
'RackRole',
|
||||
)
|
||||
@@ -41,11 +40,10 @@ __all__ = (
|
||||
#
|
||||
|
||||
@extras_features('custom_fields', 'export_templates', 'webhooks')
|
||||
class RackGroup(NestedGroupModel):
|
||||
class Location(NestedGroupModel):
|
||||
"""
|
||||
Racks can be grouped as subsets within a Site. The scope of a group will depend on how Sites are defined. For
|
||||
example, if a Site spans a corporate campus, a RackGroup might be defined to represent each building within that
|
||||
campus. If a Site instead represents a single building, a RackGroup might represent a single room or floor.
|
||||
A Location represents a subgroup of Racks and/or Devices within a Site. A Location may represent a building within a
|
||||
site, or a room within a building, for example.
|
||||
"""
|
||||
name = models.CharField(
|
||||
max_length=100
|
||||
@@ -56,7 +54,7 @@ class RackGroup(NestedGroupModel):
|
||||
site = models.ForeignKey(
|
||||
to='dcim.Site',
|
||||
on_delete=models.CASCADE,
|
||||
related_name='rack_groups'
|
||||
related_name='locations'
|
||||
)
|
||||
parent = TreeForeignKey(
|
||||
to='self',
|
||||
@@ -81,7 +79,7 @@ class RackGroup(NestedGroupModel):
|
||||
]
|
||||
|
||||
def get_absolute_url(self):
|
||||
return "{}?group_id={}".format(reverse('dcim:rack_list'), self.pk)
|
||||
return "{}?location_id={}".format(reverse('dcim:rack_list'), self.pk)
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
@@ -95,9 +93,9 @@ class RackGroup(NestedGroupModel):
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# Parent RackGroup (if any) must belong to the same Site
|
||||
# Parent Location (if any) must belong to the same Site
|
||||
if self.parent and self.parent.site != self.site:
|
||||
raise ValidationError(f"Parent rack group ({self.parent}) must belong to the same site ({self.site})")
|
||||
raise ValidationError(f"Parent location ({self.parent}) must belong to the same site ({self.site})")
|
||||
|
||||
|
||||
@extras_features('custom_fields', 'export_templates', 'webhooks')
|
||||
@@ -147,7 +145,7 @@ class RackRole(OrganizationalModel):
|
||||
class Rack(PrimaryModel):
|
||||
"""
|
||||
Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face.
|
||||
Each Rack is assigned to a Site and (optionally) a RackGroup.
|
||||
Each Rack is assigned to a Site and (optionally) a Location.
|
||||
"""
|
||||
name = models.CharField(
|
||||
max_length=100
|
||||
@@ -169,13 +167,12 @@ class Rack(PrimaryModel):
|
||||
on_delete=models.PROTECT,
|
||||
related_name='racks'
|
||||
)
|
||||
group = models.ForeignKey(
|
||||
to='dcim.RackGroup',
|
||||
location = models.ForeignKey(
|
||||
to='dcim.Location',
|
||||
on_delete=models.SET_NULL,
|
||||
related_name='racks',
|
||||
blank=True,
|
||||
null=True,
|
||||
help_text='Assigned group'
|
||||
null=True
|
||||
)
|
||||
tenant = models.ForeignKey(
|
||||
to='tenancy.Tenant',
|
||||
@@ -259,20 +256,20 @@ class Rack(PrimaryModel):
|
||||
objects = RestrictedQuerySet.as_manager()
|
||||
|
||||
csv_headers = [
|
||||
'site', 'group', 'name', 'facility_id', 'tenant', 'status', 'role', 'type', 'serial', 'asset_tag', 'width',
|
||||
'site', 'location', 'name', 'facility_id', 'tenant', 'status', 'role', 'type', 'serial', 'asset_tag', 'width',
|
||||
'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'comments',
|
||||
]
|
||||
clone_fields = [
|
||||
'site', 'group', 'tenant', 'status', 'role', 'type', 'width', 'u_height', 'desc_units', 'outer_width',
|
||||
'site', 'location', 'tenant', 'status', 'role', 'type', 'width', 'u_height', 'desc_units', 'outer_width',
|
||||
'outer_depth', 'outer_unit',
|
||||
]
|
||||
|
||||
class Meta:
|
||||
ordering = ('site', 'group', '_name', 'pk') # (site, group, name) may be non-unique
|
||||
ordering = ('site', 'location', '_name', 'pk') # (site, location, name) may be non-unique
|
||||
unique_together = (
|
||||
# Name and facility_id must be unique *only* within a RackGroup
|
||||
('group', 'name'),
|
||||
('group', 'facility_id'),
|
||||
# Name and facility_id must be unique *only* within a Location
|
||||
('location', 'name'),
|
||||
('location', 'facility_id'),
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
@@ -284,9 +281,9 @@ class Rack(PrimaryModel):
|
||||
def clean(self):
|
||||
super().clean()
|
||||
|
||||
# Validate group/site assignment
|
||||
if self.site and self.group and self.group.site != self.site:
|
||||
raise ValidationError(f"Assigned rack group must belong to parent site ({self.site}).")
|
||||
# Validate location/site assignment
|
||||
if self.site and self.location and self.location.site != self.site:
|
||||
raise ValidationError(f"Assigned location must belong to parent site ({self.site}).")
|
||||
|
||||
# Validate outer dimensions and unit
|
||||
if (self.outer_width is not None or self.outer_depth is not None) and not self.outer_unit:
|
||||
@@ -309,17 +306,17 @@ class Rack(PrimaryModel):
|
||||
min_height
|
||||
)
|
||||
})
|
||||
# Validate that Rack was assigned a group of its same site, if applicable
|
||||
if self.group:
|
||||
if self.group.site != self.site:
|
||||
# Validate that Rack was assigned a Location of its same site, if applicable
|
||||
if self.location:
|
||||
if self.location.site != self.site:
|
||||
raise ValidationError({
|
||||
'group': "Rack group must be from the same site, {}.".format(self.site)
|
||||
'location': f"Location must be from the same site, {self.site}."
|
||||
})
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
self.site.name,
|
||||
self.group.name if self.group else None,
|
||||
self.location.name if self.location else None,
|
||||
self.name,
|
||||
self.facility_id,
|
||||
self.tenant.name if self.tenant else None,
|
||||
@@ -565,7 +562,7 @@ class RackReservation(PrimaryModel):
|
||||
|
||||
objects = RestrictedQuerySet.as_manager()
|
||||
|
||||
csv_headers = ['site', 'rack_group', 'rack', 'units', 'tenant', 'user', 'description']
|
||||
csv_headers = ['site', 'location', 'rack', 'units', 'tenant', 'user', 'description']
|
||||
|
||||
class Meta:
|
||||
ordering = ['created', 'pk']
|
||||
@@ -606,7 +603,7 @@ class RackReservation(PrimaryModel):
|
||||
def to_csv(self):
|
||||
return (
|
||||
self.rack.site.name,
|
||||
self.rack.group if self.rack.group else None,
|
||||
self.rack.location if self.rack.location else None,
|
||||
self.rack.name,
|
||||
','.join([str(u) for u in self.units]),
|
||||
self.tenant.name if self.tenant else None,
|
||||
|
Reference in New Issue
Block a user