diff --git a/docs/models/wireless/wirelesslink.md b/docs/models/wireless/wirelesslink.md index 8018c0d16..e670b69ec 100644 --- a/docs/models/wireless/wirelesslink.md +++ b/docs/models/wireless/wirelesslink.md @@ -41,6 +41,6 @@ The security cipher used to apply wireless authentication. Options include: The security key configured on each client to grant access to the secured wireless LAN. This applies only to certain authentication types. -### Length +### Distance -The numeric length of the link, including a unit designation (e.g. 100 meters or 25 feet). +The numeric distance of the link, including a unit designation (e.g. 100 meters or 25 feet). diff --git a/netbox/dcim/forms/model_forms.py b/netbox/dcim/forms/model_forms.py index d5cc0e856..c1ed1049f 100644 --- a/netbox/dcim/forms/model_forms.py +++ b/netbox/dcim/forms/model_forms.py @@ -656,11 +656,6 @@ class CableForm(TenancyForm, NetBoxModelForm): 'a_terminations_type', 'b_terminations_type', 'type', 'status', 'tenant_group', 'tenant', 'label', 'color', 'length', 'length_unit', 'description', 'comments', 'tags', ] - error_messages = { - 'length': { - 'max_value': _('Maximum length is 32767 (any unit)') - } - } class PowerPanelForm(NetBoxModelForm): diff --git a/netbox/dcim/svg/cables.py b/netbox/dcim/svg/cables.py index 9aea47afb..959414d75 100644 --- a/netbox/dcim/svg/cables.py +++ b/netbox/dcim/svg/cables.py @@ -393,8 +393,8 @@ class CableTraceSVG: labels = [f"{cable}"] if len(links) > 2 else [f"Wireless {cable}", cable.get_status_display()] if cable.ssid: description.append(f"{cable.ssid}") - if cable.length and cable.length_unit: - description.append(f"{cable.length} {cable.get_length_unit_display()}") + if cable.distance and cable.distance_unit: + description.append(f"{cable.distance} {cable.get_distance_unit_display()}") near = [term for term in near_terminations if term.object == cable.interface_a] far = [term for term in far_terminations if term.object == cable.interface_b] if not (near and far): diff --git a/netbox/templates/wireless/wirelesslink.html b/netbox/templates/wireless/wirelesslink.html index 4c606c092..fe444d093 100644 --- a/netbox/templates/wireless/wirelesslink.html +++ b/netbox/templates/wireless/wirelesslink.html @@ -37,8 +37,8 @@ {% trans "Length" %} - {% if object.length is not None %} - {{ object.length|floatformat }} {{ object.get_length_unit_display }} + {% if object.distance is not None %} + {{ object.distance|floatformat }} {{ object.get_distance_unit_display }} {% else %} {{ ''|placeholder }} {% endif %} diff --git a/netbox/wireless/api/serializers_/wirelesslinks.py b/netbox/wireless/api/serializers_/wirelesslinks.py index 9d7821ba0..7c8138f9b 100644 --- a/netbox/wireless/api/serializers_/wirelesslinks.py +++ b/netbox/wireless/api/serializers_/wirelesslinks.py @@ -21,13 +21,13 @@ class WirelessLinkSerializer(NetBoxModelSerializer): tenant = TenantSerializer(nested=True, required=False, allow_null=True) auth_type = ChoiceField(choices=WirelessAuthTypeChoices, required=False, allow_blank=True) auth_cipher = ChoiceField(choices=WirelessAuthCipherChoices, required=False, allow_blank=True) - length_unit = ChoiceField(choices=WirelessLinkLengthUnitChoices, allow_blank=True, required=False, allow_null=True) + distance_unit = ChoiceField(choices=WirelessLinkDistanceUnitChoices, allow_blank=True, required=False, allow_null=True) class Meta: model = WirelessLink fields = [ 'id', 'url', 'display', 'interface_a', 'interface_b', 'ssid', 'status', 'tenant', 'auth_type', - 'auth_cipher', 'auth_psk', 'length', 'length_unit', 'description', 'comments', 'tags', 'custom_fields', + 'auth_cipher', 'auth_psk', 'distance', 'distance_unit', 'description', 'comments', 'tags', 'custom_fields', 'created', 'last_updated', ] brief_fields = ('id', 'url', 'display', 'ssid', 'description') diff --git a/netbox/wireless/choices.py b/netbox/wireless/choices.py index b943765ed..f17ea584d 100644 --- a/netbox/wireless/choices.py +++ b/netbox/wireless/choices.py @@ -483,7 +483,7 @@ class WirelessAuthCipherChoices(ChoiceSet): ) -class WirelessLinkLengthUnitChoices(ChoiceSet): +class WirelessLinkDistanceUnitChoices(ChoiceSet): # Metric UNIT_KILOMETER = 'km' diff --git a/netbox/wireless/filtersets.py b/netbox/wireless/filtersets.py index 1d9c878e9..9f60388ce 100644 --- a/netbox/wireless/filtersets.py +++ b/netbox/wireless/filtersets.py @@ -105,7 +105,7 @@ class WirelessLinkFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class Meta: model = WirelessLink - fields = ('id', 'ssid', 'auth_psk', 'length', 'length_unit', 'description') + fields = ('id', 'ssid', 'auth_psk', 'distance', 'distance_unit', 'description') def search(self, queryset, name, value): if not value.strip(): diff --git a/netbox/wireless/forms/bulk_edit.py b/netbox/wireless/forms/bulk_edit.py index 36a345c2c..5d43de25a 100644 --- a/netbox/wireless/forms/bulk_edit.py +++ b/netbox/wireless/forms/bulk_edit.py @@ -125,14 +125,14 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm): required=False, label=_('Pre-shared key') ) - length = forms.DecimalField( - label=_('Length'), + distance = forms.DecimalField( + label=_('Distance'), min_value=0, required=False ) - length_unit = forms.ChoiceField( - label=_('Length unit'), - choices=add_blank_choice(WirelessLinkLengthUnitChoices), + distance_unit = forms.ChoiceField( + label=_('Distance unit'), + choices=add_blank_choice(WirelessLinkDistanceUnitChoices), required=False, initial='' ) @@ -147,7 +147,7 @@ class WirelessLinkBulkEditForm(NetBoxModelBulkEditForm): fieldsets = ( FieldSet('ssid', 'status', 'tenant', 'description'), FieldSet('auth_type', 'auth_cipher', 'auth_psk', name=_('Authentication')), - FieldSet('length', 'length_unit', name=_('Attributes')), + FieldSet('distance', 'distance_unit', name=_('Attributes')), ) nullable_fields = ( 'ssid', 'tenant', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'length', 'comments', diff --git a/netbox/wireless/forms/bulk_import.py b/netbox/wireless/forms/bulk_import.py index 8413cd467..197d258bf 100644 --- a/netbox/wireless/forms/bulk_import.py +++ b/netbox/wireless/forms/bulk_import.py @@ -112,16 +112,16 @@ class WirelessLinkImportForm(NetBoxModelImportForm): required=False, help_text=_('Authentication cipher') ) - length_unit = CSVChoiceField( + distance_unit = CSVChoiceField( label=_('Length unit'), - choices=WirelessLinkLengthUnitChoices, + choices=WirelessLinkDistanceUnitChoices, required=False, - help_text=_('Length unit') + help_text=_('Distance unit') ) class Meta: model = WirelessLink fields = ( 'interface_a', 'interface_b', 'ssid', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', - 'length', 'length_unit', 'description', 'comments', 'tags', + 'distance', 'distance_unit', 'description', 'comments', 'tags', ) diff --git a/netbox/wireless/forms/filtersets.py b/netbox/wireless/forms/filtersets.py index 6e68546f6..b28784805 100644 --- a/netbox/wireless/forms/filtersets.py +++ b/netbox/wireless/forms/filtersets.py @@ -98,13 +98,13 @@ class WirelessLinkFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm): label=_('Pre-shared key'), required=False ) - length = forms.DecimalField( - label=_('Length'), + distance = forms.DecimalField( + label=_('Distance'), required=False, ) - length_unit = forms.ChoiceField( - label=_('Length unit'), - choices=add_blank_choice(WirelessLinkLengthUnitChoices), + distance_unit = forms.ChoiceField( + label=_('Distance unit'), + choices=add_blank_choice(WirelessLinkDistanceUnitChoices), required=False ) tag = TagFilterField(model) diff --git a/netbox/wireless/forms/model_forms.py b/netbox/wireless/forms/model_forms.py index 9f39aac96..648a52e89 100644 --- a/netbox/wireless/forms/model_forms.py +++ b/netbox/wireless/forms/model_forms.py @@ -169,7 +169,7 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm): fields = [ 'site_a', 'location_a', 'device_a', 'interface_a', 'site_b', 'location_b', 'device_b', 'interface_b', 'status', 'ssid', 'tenant_group', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', - 'length', 'length_unit', 'description', 'comments', 'tags', + 'distance', 'distance_unit', 'description', 'comments', 'tags', ] widgets = { 'auth_psk': PasswordInput( @@ -181,8 +181,3 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm): 'auth_type': 'Type', 'auth_cipher': 'Cipher', } - error_messages = { - 'length': { - 'max_value': _('Maximum length is 32767 (any unit)') - } - } diff --git a/netbox/wireless/migrations/0009_wirelesslink_length.py b/netbox/wireless/migrations/0009_wirelesslink_length.py deleted file mode 100644 index 43f522971..000000000 --- a/netbox/wireless/migrations/0009_wirelesslink_length.py +++ /dev/null @@ -1,28 +0,0 @@ -# Generated by Django 5.0.6 on 2024-06-12 18:15 - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('wireless', '0001_squashed_0008'), - ] - - operations = [ - migrations.AddField( - model_name='wirelesslink', - name='_abs_length', - field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True), - ), - migrations.AddField( - model_name='wirelesslink', - name='length', - field=models.DecimalField(blank=True, decimal_places=2, max_digits=8, null=True), - ), - migrations.AddField( - model_name='wirelesslink', - name='length_unit', - field=models.CharField(blank=True, max_length=50), - ), - ] diff --git a/netbox/wireless/models.py b/netbox/wireless/models.py index 009e58162..9c5917544 100644 --- a/netbox/wireless/models.py +++ b/netbox/wireless/models.py @@ -161,21 +161,21 @@ class WirelessLink(WirelessAuthenticationBase, PrimaryModel): choices=LinkStatusChoices, default=LinkStatusChoices.STATUS_CONNECTED ) - length = models.DecimalField( - verbose_name=_('length'), + distance = models.DecimalField( + verbose_name=_('distance'), max_digits=8, decimal_places=2, blank=True, null=True ) - length_unit = models.CharField( - verbose_name=_('length unit'), + distance_unit = models.CharField( + verbose_name=_('distance unit'), max_length=50, - choices=WirelessLinkLengthUnitChoices, + choices=WirelessLinkDistanceUnitChoices, blank=True, ) # Stores the normalized length (in meters) for database ordering - _abs_length = models.DecimalField( + _abs_distance = models.DecimalField( max_digits=10, decimal_places=4, blank=True, @@ -229,6 +229,11 @@ class WirelessLink(WirelessAuthenticationBase, PrimaryModel): return LinkStatusChoices.colors.get(self.status) def clean(self): + super().clean() + + # Validate distance and distance_unit + if self.distance is not None and not self.distance_unit: + raise ValidationError(_("Must specify a unit when setting a wireless distance")) # Validate interface types if self.interface_a.type not in WIRELESS_IFACE_TYPES: @@ -247,9 +252,9 @@ class WirelessLink(WirelessAuthenticationBase, PrimaryModel): def save(self, *args, **kwargs): # Store the given length (if any) in meters for use in database ordering if self.length is not None and self.length_unit: - self._abs_length = to_meters(self.length, self.length_unit) + self._abs_distance = to_meters(self.length, self.length_unit) else: - self._abs_length = None + self._abs_distance = None # Clear length_unit if no length is defined if self.length is None: diff --git a/netbox/wireless/tables/template_code.py b/netbox/wireless/tables/template_code.py index 885e5ffc4..03c893c1f 100644 --- a/netbox/wireless/tables/template_code.py +++ b/netbox/wireless/tables/template_code.py @@ -1,4 +1,4 @@ -WIRELESS_LINK_LENGTH = """ +WIRELESS_LINK_DISTANCE = """ {% load helpers %} -{% if record.length %}{{ record.length|floatformat:"-2" }} {{ record.length_unit }}{% endif %} +{% if record.distance %}{{ record.distance|floatformat:"-2" }} {{ record.distance_unit }}{% endif %} """ diff --git a/netbox/wireless/tables/wirelesslink.py b/netbox/wireless/tables/wirelesslink.py index 0c4725517..fad8405a5 100644 --- a/netbox/wireless/tables/wirelesslink.py +++ b/netbox/wireless/tables/wirelesslink.py @@ -4,7 +4,7 @@ import django_tables2 as tables from netbox.tables import NetBoxTable, columns from tenancy.tables import TenancyColumnsMixin from wireless.models import * -from .template_code import WIRELESS_LINK_LENGTH +from .template_code import WIRELESS_LINK_DISTANCE __all__ = ( 'WirelessLinkTable', @@ -37,9 +37,9 @@ class WirelessLinkTable(TenancyColumnsMixin, NetBoxTable): verbose_name=_('Interface B'), linkify=True ) - length = columns.TemplateColumn( - template_code=WIRELESS_LINK_LENGTH, - order_by=('_abs_length', 'length_unit') + distance = columns.TemplateColumn( + template_code=WIRELESS_LINK_DISTANCE, + order_by=('_abs_distance', 'distance_unit') ) tags = columns.TagColumn( url_name='wireless:wirelesslink_list' @@ -49,7 +49,7 @@ class WirelessLinkTable(TenancyColumnsMixin, NetBoxTable): model = WirelessLink fields = ( 'pk', 'id', 'status', 'device_a', 'interface_a', 'device_b', 'interface_b', 'ssid', 'tenant', - 'tenant_group', 'length', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'tags', + 'tenant_group', 'distance', 'description', 'auth_type', 'auth_cipher', 'auth_psk', 'tags', 'created', 'last_updated', ) default_columns = ( diff --git a/netbox/wireless/tests/test_api.py b/netbox/wireless/tests/test_api.py index 400cc1d96..cd26debf7 100644 --- a/netbox/wireless/tests/test_api.py +++ b/netbox/wireless/tests/test_api.py @@ -113,8 +113,8 @@ class WirelessLinkTest(APIViewTestCases.APIViewTestCase): brief_fields = ['description', 'display', 'id', 'ssid', 'url'] bulk_update_data = { 'status': 'planned', - 'length': 100, - 'length_unit': 'm', + 'distance': 100, + 'distance_unit': 'm', } @classmethod diff --git a/netbox/wireless/tests/test_filtersets.py b/netbox/wireless/tests/test_filtersets.py index e5fdfad20..46eec4d7b 100644 --- a/netbox/wireless/tests/test_filtersets.py +++ b/netbox/wireless/tests/test_filtersets.py @@ -260,8 +260,8 @@ class WirelessLinkTestCase(TestCase, ChangeLoggedFilterSetTests): auth_cipher=WirelessAuthCipherChoices.CIPHER_AUTO, auth_psk='PSK1', tenant=tenants[0], - length=10, - length_unit=WirelessLinkLengthUnitChoices.UNIT_FOOT, + distance=10, + distance_unit=WirelessLinkDistanceUnitChoices.UNIT_FOOT, description='foobar1' ).save() WirelessLink( @@ -273,8 +273,8 @@ class WirelessLinkTestCase(TestCase, ChangeLoggedFilterSetTests): auth_cipher=WirelessAuthCipherChoices.CIPHER_TKIP, auth_psk='PSK2', tenant=tenants[1], - length=20, - length_unit=WirelessLinkLengthUnitChoices.UNIT_METER, + distance=20, + distance_unit=WirelessLinkDistanceUnitChoices.UNIT_METER, description='foobar2' ).save() WirelessLink( @@ -285,8 +285,8 @@ class WirelessLinkTestCase(TestCase, ChangeLoggedFilterSetTests): auth_type=WirelessAuthTypeChoices.TYPE_WPA_PERSONAL, auth_cipher=WirelessAuthCipherChoices.CIPHER_AES, auth_psk='PSK3', - length=30, - length_unit=WirelessLinkLengthUnitChoices.UNIT_METER, + distance=30, + distance_unit=WirelessLinkDistanceUnitChoices.UNIT_METER, tenant=tenants[2], ).save() WirelessLink( @@ -319,12 +319,12 @@ class WirelessLinkTestCase(TestCase, ChangeLoggedFilterSetTests): params = {'auth_psk': ['PSK1', 'PSK2']} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_length(self): - params = {'length': [10, 20]} + def test_distance(self): + params = {'distance': [10, 20]} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 2) - def test_length_unit(self): - params = {'length_unit': WirelessLinkLengthUnitChoices.UNIT_FOOT} + def test_distance_unit(self): + params = {'distance_unit': WirelessLinkDistanceUnitChoices.UNIT_FOOT} self.assertEqual(self.filterset(params, self.queryset).qs.count(), 1) def test_description(self): diff --git a/netbox/wireless/tests/test_views.py b/netbox/wireless/tests/test_views.py index d897fe99a..055edf73c 100644 --- a/netbox/wireless/tests/test_views.py +++ b/netbox/wireless/tests/test_views.py @@ -160,8 +160,8 @@ class WirelessLinkTestCase(ViewTestCases.PrimaryObjectViewTestCase): 'interface_a': interfaces[6].pk, 'interface_b': interfaces[7].pk, 'status': LinkStatusChoices.STATUS_PLANNED, - 'length': 100, - 'length_unit': WirelessLinkLengthUnitChoices.UNIT_FOOT, + 'distance': 100, + 'distance_unit': WirelessLinkDistanceUnitChoices.UNIT_FOOT, 'tenant': tenants[1].pk, 'tags': [t.pk for t in tags], } @@ -182,6 +182,6 @@ class WirelessLinkTestCase(ViewTestCases.PrimaryObjectViewTestCase): cls.bulk_edit_data = { 'status': LinkStatusChoices.STATUS_PLANNED, - 'length': 50, - 'length_unit': WirelessLinkLengthUnitChoices.UNIT_METER, + 'distance': 50, + 'distance_unit': WirelessLinkDistanceUnitChoices.UNIT_METER, }