From c79c29e7692483f64f5375a0634cc44d5369a98a Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 15 Nov 2019 22:03:41 -0500 Subject: [PATCH] Rack.status to slug (#3569) --- netbox/dcim/api/serializers.py | 2 +- netbox/dcim/choices.py | 25 ++++++++++++++++++ netbox/dcim/constants.py | 16 +----------- netbox/dcim/filters.py | 2 +- netbox/dcim/forms.py | 6 ++--- .../0078_rack_choicefields_to_slugs.py | 26 ++++++++++++++++++- netbox/dcim/models.py | 17 +++++++++--- 7 files changed, 69 insertions(+), 25 deletions(-) diff --git a/netbox/dcim/api/serializers.py b/netbox/dcim/api/serializers.py index 67450d7b1..c696e4d2a 100644 --- a/netbox/dcim/api/serializers.py +++ b/netbox/dcim/api/serializers.py @@ -115,7 +115,7 @@ class RackSerializer(TaggitSerializer, CustomFieldModelSerializer): site = NestedSiteSerializer() group = NestedRackGroupSerializer(required=False, allow_null=True, default=None) tenant = NestedTenantSerializer(required=False, allow_null=True) - status = ChoiceField(choices=RACK_STATUS_CHOICES, required=False) + status = ChoiceField(choices=RackStatusChoices, required=False) role = NestedRackRoleSerializer(required=False, allow_null=True) type = ChoiceField(choices=RackTypeChoices, required=False, allow_null=True) width = ChoiceField(choices=RackWidthChoices, required=False) diff --git a/netbox/dcim/choices.py b/netbox/dcim/choices.py index c75568ee8..4ebeac047 100644 --- a/netbox/dcim/choices.py +++ b/netbox/dcim/choices.py @@ -41,6 +41,31 @@ class RackWidthChoices(ChoiceSet): ) +class RackStatusChoices(ChoiceSet): + + STATUS_RESERVED = 'reserved' + STATUS_AVAILABLE = 'available' + STATUS_PLANNED = 'planned' + STATUS_ACTIVE = 'active' + STATUS_DEPRECATED = 'deprecated' + + CHOICES = ( + (STATUS_RESERVED, 'Reserved'), + (STATUS_AVAILABLE, 'Available'), + (STATUS_PLANNED, 'Planned'), + (STATUS_ACTIVE, 'Active'), + (STATUS_DEPRECATED, 'Deprecated'), + ) + + LEGACY_MAP = { + STATUS_RESERVED: 0, + STATUS_AVAILABLE: 1, + STATUS_PLANNED: 2, + STATUS_ACTIVE: 3, + STATUS_DEPRECATED: 4, + } + + # # Console port type values # diff --git a/netbox/dcim/constants.py b/netbox/dcim/constants.py index c6f4ced5f..6a6e9e521 100644 --- a/netbox/dcim/constants.py +++ b/netbox/dcim/constants.py @@ -1,4 +1,4 @@ -# Rack faces +# Device rack faces RACK_FACE_FRONT = 0 RACK_FACE_REAR = 1 RACK_FACE_CHOICES = [ @@ -6,20 +6,6 @@ RACK_FACE_CHOICES = [ [RACK_FACE_REAR, 'Rear'], ] -# Rack statuses -RACK_STATUS_RESERVED = 0 -RACK_STATUS_AVAILABLE = 1 -RACK_STATUS_PLANNED = 2 -RACK_STATUS_ACTIVE = 3 -RACK_STATUS_DEPRECATED = 4 -RACK_STATUS_CHOICES = [ - [RACK_STATUS_ACTIVE, 'Active'], - [RACK_STATUS_PLANNED, 'Planned'], - [RACK_STATUS_RESERVED, 'Reserved'], - [RACK_STATUS_AVAILABLE, 'Available'], - [RACK_STATUS_DEPRECATED, 'Deprecated'], -] - # Device rack position DEVICE_POSITION_CHOICES = [ # Rack.u_height is limited to 100 diff --git a/netbox/dcim/filters.py b/netbox/dcim/filters.py index 10a7dae96..aa5113ff1 100644 --- a/netbox/dcim/filters.py +++ b/netbox/dcim/filters.py @@ -147,7 +147,7 @@ class RackFilter(TenancyFilterSet, CustomFieldFilterSet): label='Group', ) status = django_filters.MultipleChoiceFilter( - choices=RACK_STATUS_CHOICES, + choices=RackStatusChoices, null_value=None ) role_id = django_filters.ModelMultipleChoiceFilter( diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 6a532741d..b487fb0a6 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -473,7 +473,7 @@ class RackCSVForm(forms.ModelForm): } ) status = CSVChoiceField( - choices=RACK_STATUS_CHOICES, + choices=RackStatusChoices, required=False, help_text='Operational status' ) @@ -568,7 +568,7 @@ class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditFor ) ) status = forms.ChoiceField( - choices=add_blank_choice(RACK_STATUS_CHOICES), + choices=add_blank_choice(RackStatusChoices), required=False, initial='', widget=StaticSelect2() @@ -662,7 +662,7 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm): ) ) status = forms.MultipleChoiceField( - choices=RACK_STATUS_CHOICES, + choices=RackStatusChoices, required=False, widget=StaticSelect2Multiple() ) diff --git a/netbox/dcim/migrations/0078_rack_choicefields_to_slugs.py b/netbox/dcim/migrations/0078_rack_choicefields_to_slugs.py index 2e5131c7a..7c9b32310 100644 --- a/netbox/dcim/migrations/0078_rack_choicefields_to_slugs.py +++ b/netbox/dcim/migrations/0078_rack_choicefields_to_slugs.py @@ -8,6 +8,14 @@ RACK_TYPE_CHOICES = ( (1100, 'wall-cabinet'), ) +RACK_STATUS_CHOICES = ( + (0, 'reserved'), + (1, 'available'), + (2, 'planned'), + (3, 'active'), + (4, 'deprecated'), +) + def rack_type_to_slug(apps, schema_editor): Rack = apps.get_model('dcim', 'Rack') @@ -15,6 +23,12 @@ def rack_type_to_slug(apps, schema_editor): Rack.objects.filter(type=str(id)).update(type=slug) +def rack_status_to_slug(apps, schema_editor): + Rack = apps.get_model('dcim', 'Rack') + for id, slug in RACK_STATUS_CHOICES: + Rack.objects.filter(status=str(id)).update(status=slug) + + class Migration(migrations.Migration): dependencies = [ @@ -22,6 +36,7 @@ class Migration(migrations.Migration): ] operations = [ + # Rack.type migrations.AlterField( model_name='rack', name='type', @@ -29,5 +44,14 @@ class Migration(migrations.Migration): ), migrations.RunPython( code=rack_type_to_slug - ) + ), + # Rack.status + migrations.AlterField( + model_name='rack', + name='status', + field=models.CharField(blank=True, max_length=50), + ), + migrations.RunPython( + code=rack_status_to_slug + ), ] diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index 5f0de7c0d..23532efa8 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -473,9 +473,10 @@ class Rack(ChangeLoggedModel, CustomFieldModel): blank=True, null=True ) - status = models.PositiveSmallIntegerField( - choices=RACK_STATUS_CHOICES, - default=RACK_STATUS_ACTIVE + status = models.CharField( + max_length=50, + choices=RackStatusChoices, + default=RackStatusChoices.STATUS_ACTIVE ) role = models.ForeignKey( to='dcim.RackRole', @@ -552,6 +553,14 @@ class Rack(ChangeLoggedModel, CustomFieldModel): 'u_height', 'desc_units', 'outer_width', 'outer_depth', 'outer_unit', 'comments', ] + STATUS_CLASS_MAP = { + RackStatusChoices.STATUS_RESERVED: 'warning', + RackStatusChoices.STATUS_AVAILABLE: 'success', + RackStatusChoices.STATUS_PLANNED: 'info', + RackStatusChoices.STATUS_ACTIVE: 'primary', + RackStatusChoices.STATUS_DEPRECATED: 'danger', + } + class Meta: ordering = ['site', 'group', 'name'] unique_together = [ @@ -644,7 +653,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel): return "" def get_status_class(self): - return STATUS_CLASSES[self.status] + return self.STATUS_CLASS_MAP.get(self.status) def get_rack_units(self, face=RACK_FACE_FRONT, exclude=None, remove_redundant=False): """