12826 add device_type to device and instantiation

This commit is contained in:
Arthur Hanson 2024-06-25 14:28:16 -07:00
parent 5a719bef38
commit 9abd45680e
6 changed files with 45 additions and 15 deletions

View File

@ -60,6 +60,7 @@ class RackSerializer(NetBoxModelSerializer):
type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False, allow_null=True) type = ChoiceField(choices=RackTypeChoices, allow_blank=True, required=False, allow_null=True)
facility_id = serializers.CharField(max_length=50, allow_blank=True, allow_null=True, label=_('Facility ID'), facility_id = serializers.CharField(max_length=50, allow_blank=True, allow_null=True, label=_('Facility ID'),
default=None) default=None)
rack_type = RackTypeSerializer(nested=True, required=False, allow_null=True, default=None)
width = ChoiceField(choices=RackWidthChoices, required=False) width = ChoiceField(choices=RackWidthChoices, required=False)
outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False, allow_null=True) outer_unit = ChoiceField(choices=RackDimensionUnitChoices, allow_blank=True, required=False, allow_null=True)
weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True) weight_unit = ChoiceField(choices=WeightUnitChoices, allow_blank=True, required=False, allow_null=True)
@ -72,9 +73,10 @@ class RackSerializer(NetBoxModelSerializer):
model = Rack model = Rack
fields = [ fields = [
'id', 'url', 'display_url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status', 'id', 'url', 'display_url', 'display', 'name', 'facility_id', 'site', 'location', 'tenant', 'status',
'role', 'serial', 'asset_tag', 'type', 'width', 'u_height', 'starting_unit', 'weight', 'max_weight', 'role', 'serial', 'asset_tag', 'rack_type', 'type', 'width', 'u_height', 'starting_unit', 'weight',
'weight_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth', 'description', 'max_weight', 'weight_unit', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'mounting_depth',
'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count', 'powerfeed_count', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', 'device_count',
'powerfeed_count',
] ]
brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count') brief_fields = ('id', 'url', 'display', 'name', 'description', 'device_count')

View File

@ -243,6 +243,11 @@ class RackForm(TenancyForm, NetBoxModelForm):
queryset=RackRole.objects.all(), queryset=RackRole.objects.all(),
required=False required=False
) )
rack_type = DynamicModelChoiceField(
label=_('Rack Type'),
queryset=RackType.objects.all(),
required=False
)
comments = CommentField() comments = CommentField()
fieldsets = ( fieldsets = (
@ -250,7 +255,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
FieldSet('facility_id', 'serial', 'asset_tag', name=_('Inventory Control')), FieldSet('facility_id', 'serial', 'asset_tag', name=_('Inventory Control')),
FieldSet('tenant_group', 'tenant', name=_('Tenancy')), FieldSet('tenant_group', 'tenant', name=_('Tenancy')),
FieldSet( FieldSet(
'type', 'width', 'starting_unit', 'u_height', 'rack_type', 'type', 'width', 'starting_unit', 'u_height',
InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')), InlineFields('outer_width', 'outer_depth', 'outer_unit', label=_('Outer Dimensions')),
InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')), InlineFields('weight', 'max_weight', 'weight_unit', label=_('Weight')),
'mounting_depth', 'desc_units', name=_('Dimensions') 'mounting_depth', 'desc_units', name=_('Dimensions')
@ -261,7 +266,7 @@ class RackForm(TenancyForm, NetBoxModelForm):
model = Rack model = Rack
fields = [ fields = [
'site', 'location', 'name', 'facility_id', 'tenant_group', 'tenant', 'status', 'role', 'serial', 'site', 'location', 'name', 'facility_id', 'tenant_group', 'tenant', 'status', 'role', 'serial',
'asset_tag', 'type', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth', 'asset_tag', 'rack_type', 'type', 'width', 'u_height', 'starting_unit', 'desc_units', 'outer_width', 'outer_depth',
'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags', 'outer_unit', 'mounting_depth', 'weight', 'max_weight', 'weight_unit', 'description', 'comments', 'tags',
] ]

View File

@ -628,6 +628,7 @@ class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObje
tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
role: Annotated["RackRoleType", strawberry.lazy('dcim.graphql.types')] | None role: Annotated["RackRoleType", strawberry.lazy('dcim.graphql.types')] | None
rack_type: Annotated["RackTypeType", strawberry.lazy('dcim.graphql.types')] | None
reservations: List[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]] reservations: List[Annotated["RackReservationType", strawberry.lazy('dcim.graphql.types')]]
devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]] devices: List[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
powerfeeds: List[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]] powerfeeds: List[Annotated["PowerFeedType", strawberry.lazy('dcim.graphql.types')]]

View File

@ -72,4 +72,15 @@ class Migration(migrations.Migration):
'ordering': ('_name', 'pk'), 'ordering': ('_name', 'pk'),
}, },
), ),
migrations.AddField(
model_name='rack',
name='rack_type',
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.PROTECT,
related_name='instances',
to='dcim.racktype',
),
),
] ]

View File

@ -37,7 +37,7 @@ __all__ = (
# Rack Types # Rack Types
# #
class RackType(ImageAttachmentsMixin, PrimaryModel, WeightMixin): class RackType(PrimaryModel, WeightMixin):
""" """
Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face. 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 Location. Each Rack is assigned to a Site and (optionally) a Location.
@ -201,6 +201,13 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, PrimaryModel, WeightMixin):
Devices are housed within Racks. Each rack has a defined height measured in rack units, and a front and rear face. 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 Location. Each Rack is assigned to a Site and (optionally) a Location.
""" """
rack_type = models.ForeignKey(
to='dcim.RackType',
on_delete=models.PROTECT,
related_name='instances',
blank=True,
null=True,
)
name = models.CharField( name = models.CharField(
verbose_name=_('name'), verbose_name=_('name'),
max_length=100 max_length=100
@ -413,6 +420,18 @@ class Rack(ContactsMixin, ImageAttachmentsMixin, PrimaryModel, WeightMixin):
}) })
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if (not self.pk) and self.rack_type:
self.width = self.rack_type.width
self.u_height = self.rack_type.u_height
self.starting_unit = self.rack_type.starting_unit
self.desc_units = self.rack_type.desc_units
self.outer_width = self.rack_type.outer_width
self.outer_depth = self.rack_type.outer_depth
self.outer_unit = self.rack_type.outer_unit
self.weight = self.rack_type.weight
self.weight_unit = self.rack_type.weight_unit
self.max_weight = self.rack_type.max_weight
self.mounting_depth = self.rack_type.mounting_depth
# Store the given max weight (if any) in grams for use in database ordering # Store the given max weight (if any) in grams for use in database ordering
if self.max_weight and self.weight_unit: if self.max_weight and self.weight_unit:

View File

@ -10,7 +10,7 @@
<div class="row"> <div class="row">
<div class="col col-12 col-xl-5"> <div class="col col-12 col-xl-5">
<div class="card"> <div class="card">
<h5 class="card-header">{% trans "Rack" %}</h5> <h5 class="card-header">{% trans "Rack Type" %}</h5>
<table class="table table-hover attr-table"> <table class="table table-hover attr-table">
<tr> <tr>
<th scope="row">{% trans "Description" %}</th> <th scope="row">{% trans "Description" %}</th>
@ -100,17 +100,9 @@
{% include 'inc/panels/custom_fields.html' %} {% include 'inc/panels/custom_fields.html' %}
{% include 'inc/panels/tags.html' %} {% include 'inc/panels/tags.html' %}
{% include 'inc/panels/comments.html' %} {% include 'inc/panels/comments.html' %}
{% include 'inc/panels/image_attachments.html' %}
{% plugin_left_page object %} {% plugin_left_page object %}
</div> </div>
<div class="col col-12 col-xl-7"> <div class="col col-12 col-xl-7">
<div class="text-end mb-4">
<select class="btn btn-outline-secondary no-ts rack-view">
<option value="images-and-labels" selected="selected">{% trans "Images and Labels" %}</option>
<option value="images-only">{% trans "Images only" %}</option>
<option value="labels-only">{% trans "Labels only" %}</option>
</select>
</div>
{% include 'inc/panels/related_objects.html' %} {% include 'inc/panels/related_objects.html' %}
{% plugin_right_page object %} {% plugin_right_page object %}
</div> </div>