Fixes #19415: Increased Circuit/WirelessLink absolute distance upper limit

Also adds form validation that provides a useful message to the user
rather than a 500 error with potentially little information.
This commit is contained in:
Jason Novinger 2025-05-14 09:36:35 -05:00
parent 6b9b5c4184
commit 7e1d558428
4 changed files with 40 additions and 4 deletions

View File

@ -16,6 +16,7 @@ from utilities.forms import get_field_value
from utilities.forms.fields import (
CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField,
)
from utilities.forms.mixins import DistanceValidationMixin
from utilities.forms.rendering import FieldSet, InlineFields
from utilities.forms.widgets import DatePicker, HTMXSelect, NumberWithOptions
from utilities.templatetags.builtins.filters import bettertitle
@ -105,7 +106,7 @@ class CircuitTypeForm(NetBoxModelForm):
]
class CircuitForm(TenancyForm, NetBoxModelForm):
class CircuitForm(DistanceValidationMixin, TenancyForm, NetBoxModelForm):
provider = DynamicModelChoiceField(
label=_('Provider'),
queryset=Provider.objects.all(),

View File

@ -55,7 +55,7 @@ class WeightMixin(models.Model):
class DistanceMixin(models.Model):
distance = models.DecimalField(
verbose_name=_('distance'),
max_digits=8,
max_digits=16,
decimal_places=2,
blank=True,
null=True
@ -69,7 +69,7 @@ class DistanceMixin(models.Model):
)
# Stores the normalized distance (in meters) for database ordering
_abs_distance = models.DecimalField(
max_digits=10,
max_digits=18,
decimal_places=4,
blank=True,
null=True

View File

@ -3,6 +3,8 @@ import time
from django import forms
from django.utils.translation import gettext_lazy as _
from utilities.conversion import to_meters
__all__ = (
'CheckLastUpdatedMixin',
)
@ -44,3 +46,35 @@ class CheckLastUpdatedMixin(forms.Form):
"This object has been modified since the form was rendered. Please consult the object's change "
"log for details."
))
class DistanceValidationMixin(forms.Form):
def clean(self):
super().clean()
# validate max distance in meters based on model
# breakpoint()
distance = self.cleaned_data.get('distance', None)
unit = self.cleaned_data.get('distance_unit', None)
if distance and unit:
model_class = self._meta.model
distance_field = model_class._meta.get_field('distance')
max_digits = distance_field.max_digits - distance_field.decimal_places
max_distance = 10 ** max_digits
abs_distance = to_meters(distance, unit)
if abs_distance > max_distance:
raise forms.ValidationError(_(
"{distance} {unit} ({abs_distance} m) exceeds the maximum allowed distance for "
"{model._meta.verbose_name} distance. Distance must normalize to no more than "
"{max_distance} meters.".format(
distance=distance,
unit=unit,
abs_distance=abs_distance,
model=model_class,
max_distance=max_distance
)
))
self.cleaned_data['_abs_distance'] = abs_distance

View File

@ -7,6 +7,7 @@ from ipam.models import VLAN
from netbox.forms import NetBoxModelForm
from tenancy.forms import TenancyForm
from utilities.forms.fields import CommentField, DynamicModelChoiceField, SlugField
from utilities.forms.mixins import DistanceValidationMixin
from utilities.forms.rendering import FieldSet, InlineFields
from wireless.models import *
@ -73,7 +74,7 @@ class WirelessLANForm(ScopedForm, TenancyForm, NetBoxModelForm):
}
class WirelessLinkForm(TenancyForm, NetBoxModelForm):
class WirelessLinkForm(DistanceValidationMixin, TenancyForm, NetBoxModelForm):
site_a = DynamicModelChoiceField(
queryset=Site.objects.all(),
required=False,