Browse Source

Merge pull request #18724 from netbox-community/18605-prefix-vlan-assignment-display

Fixes #18605: only VLANs at selected Site are shown in VLAN select
bctiemann 11 months ago
parent
commit
4fb42ac7b3
2 changed files with 52 additions and 1 deletions
  1. 9 1
      netbox/ipam/forms/model_forms.py
  2. 43 0
      netbox/ipam/tests/test_forms.py

+ 9 - 1
netbox/ipam/forms/model_forms.py

@@ -212,7 +212,7 @@ class PrefixForm(TenancyForm, ScopedForm, NetBoxModelForm):
         required=False,
         required=False,
         selector=True,
         selector=True,
         query_params={
         query_params={
-            'available_at_site': '$site',
+            'available_at_site': '$scope',
         },
         },
         label=_('VLAN'),
         label=_('VLAN'),
     )
     )
@@ -240,6 +240,14 @@ class PrefixForm(TenancyForm, ScopedForm, NetBoxModelForm):
             'tenant', 'description', 'comments', 'tags',
             '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):
 class IPRangeForm(TenancyForm, NetBoxModelForm):
     vrf = DynamicModelChoiceField(
     vrf = DynamicModelChoiceField(

+ 43 - 0
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