From 64270d6a4e99770dab38870a866e14c72518b27b Mon Sep 17 00:00:00 2001 From: Jason Novinger Date: Mon, 24 Feb 2025 11:29:31 -0600 Subject: [PATCH] Fixes #18605: only VLANs at selected Site are shown in VLAN select --- netbox/ipam/forms/model_forms.py | 10 +++++++- netbox/ipam/tests/test_forms.py | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 netbox/ipam/tests/test_forms.py diff --git a/netbox/ipam/forms/model_forms.py b/netbox/ipam/forms/model_forms.py index c381f99c9..e7fccfe82 100644 --- a/netbox/ipam/forms/model_forms.py +++ b/netbox/ipam/forms/model_forms.py @@ -212,7 +212,7 @@ class PrefixForm(TenancyForm, ScopedForm, NetBoxModelForm): required=False, selector=True, query_params={ - 'available_at_site': '$site', + 'available_at_site': '$scope', }, label=_('VLAN'), ) @@ -240,6 +240,14 @@ class PrefixForm(TenancyForm, ScopedForm, NetBoxModelForm): 'tenant', 'description', 'comments', 'tags', ] + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # #18605: only filter VLAN select list if scope field is a Site + if scope_field := self.fields.get('scope', None): + if scope_field.queryset.model is not Site: + self.fields['vlan'].widget.attrs.pop('data-dynamic-params', None) + class IPRangeForm(TenancyForm, NetBoxModelForm): vrf = DynamicModelChoiceField( diff --git a/netbox/ipam/tests/test_forms.py b/netbox/ipam/tests/test_forms.py new file mode 100644 index 000000000..d345c42b1 --- /dev/null +++ b/netbox/ipam/tests/test_forms.py @@ -0,0 +1,43 @@ +from django.contrib.contenttypes.models import ContentType +from django.test import TestCase + +from dcim.models import Location, Region, Site, SiteGroup +from ipam.forms import PrefixForm + + +class PrefixFormTestCase(TestCase): + default_dynamic_params = '[{"fieldName":"scope","queryParam":"available_at_site"}]' + + @classmethod + def setUpTestData(cls): + cls.site = Site.objects.create(name='Site 1', slug='site-1') + + def test_vlan_field_sets_dynamic_params_by_default(self): + """data-dynamic-params present when no scope_type selected""" + form = PrefixForm(data={}) + + assert form.fields['vlan'].widget.attrs['data-dynamic-params'] == self.default_dynamic_params + + def test_vlan_field_sets_dynamic_params_for_scope_site(self): + """data-dynamic-params present when scope type is Site and when scope is specifc site""" + form = PrefixForm(data={ + 'scope_type': ContentType.objects.get_for_model(Site).id, + 'scope': self.site, + }) + + assert form.fields['vlan'].widget.attrs['data-dynamic-params'] == self.default_dynamic_params + + def test_vlan_field_does_not_set_dynamic_params_for_other_scopes(self): + """data-dynamic-params not present when scope type is populated by is not Site""" + cases = [ + Region(name='Region 1', slug='region-1'), + Location(site=self.site, name='Location 1', slug='location-1'), + SiteGroup(name='Site Group 1', slug='site-group-1'), + ] + for case in cases: + form = PrefixForm(data={ + 'scope_type': ContentType.objects.get_for_model(case._meta.model).id, + 'scope': case, + }) + + assert 'data-dynamic-params' not in form.fields['vlan'].widget.attrs