This commit is contained in:
parent
84a024babd
commit
3e3d36cc2d
|
|
@ -1069,6 +1069,10 @@ class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
|||
queryset=Site.objects.all(),
|
||||
method='get_for_site'
|
||||
)
|
||||
available_at_site_group = django_filters.ModelChoiceFilter(
|
||||
queryset=SiteGroup.objects.all(),
|
||||
method='get_for_site_group'
|
||||
)
|
||||
available_on_device = django_filters.ModelChoiceFilter(
|
||||
queryset=Device.objects.select_related('cluster'),
|
||||
method='get_for_device'
|
||||
|
|
@ -1130,6 +1134,10 @@ class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
|
|||
def get_for_site(self, queryset, name, value):
|
||||
return queryset.get_for_site(value)
|
||||
|
||||
@extend_schema_field(OpenApiTypes.STR)
|
||||
def get_for_site_group(self, queryset, name, value):
|
||||
return queryset.get_for_site_group(value)
|
||||
|
||||
@extend_schema_field(OpenApiTypes.STR)
|
||||
def get_for_device(self, queryset, name, value):
|
||||
return queryset.get_for_device(value)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ from django.utils.safestring import mark_safe
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from dcim.forms.mixins import ScopedForm
|
||||
from dcim.models import Device, Interface, Site
|
||||
from dcim.models import Device, Interface, Site, SiteGroup
|
||||
from ipam.choices import *
|
||||
from ipam.constants import *
|
||||
from ipam.formfields import IPNetworkFormField
|
||||
|
|
@ -245,9 +245,17 @@ class PrefixForm(TenancyForm, ScopedForm, PrimaryModelForm):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# #18605: only filter VLAN select list if scope field is a Site
|
||||
# #18605: only filter VLAN select list if scope field is a Site or Site Group
|
||||
if scope_field := self.fields.get('scope', None):
|
||||
if scope_field.queryset.model is not Site:
|
||||
if scope_field.queryset.model is Site:
|
||||
pass # already filtered by available_at_site
|
||||
elif scope_field.queryset.model is SiteGroup:
|
||||
self.fields['vlan'].widget.dynamic_params.clear()
|
||||
self.fields['vlan'].widget.attrs.pop('data-dynamic-params', None)
|
||||
self.fields['vlan'].widget.add_query_params({
|
||||
'available_at_site_group': '$scope',
|
||||
})
|
||||
else:
|
||||
self.fields['vlan'].widget.attrs.pop('data-dynamic-params', None)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -290,6 +290,23 @@ class VLANQuerySet(RestrictedQuerySet):
|
|||
Q(group__isnull=True, site__isnull=True) # Global VLANs
|
||||
)
|
||||
|
||||
def get_for_site_group(self, site_group):
|
||||
"""
|
||||
Return all VLANs available to the specified site group.
|
||||
"""
|
||||
if site_group is None:
|
||||
return self.none()
|
||||
from .models import VLANGroup
|
||||
q = Q(
|
||||
scope_type=ContentType.objects.get_by_natural_key('dcim', 'sitegroup'),
|
||||
scope_id__in=site_group.get_ancestors(include_self=True)
|
||||
)
|
||||
return self.filter(
|
||||
Q(group__in=VLANGroup.objects.filter(q)) |
|
||||
Q(group__scope_id__isnull=True, site__isnull=True) | # Global group VLANs
|
||||
Q(group__isnull=True, site__isnull=True) # Global VLANs
|
||||
)
|
||||
|
||||
def get_for_device(self, device):
|
||||
"""
|
||||
Return all VLANs available to the specified Device.
|
||||
|
|
|
|||
|
|
@ -2221,6 +2221,11 @@ class VLANTestCase(TestCase, ChangeLoggedFilterSetTests):
|
|||
params = {'available_at_site': site_id}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 5) # 4 scoped + 1 global group + 1 global
|
||||
|
||||
def test_available_at_site_group(self):
|
||||
site_group = SiteGroup.objects.get(name='Site Group 1')
|
||||
params = {'available_at_site_group': site_group.pk}
|
||||
self.assertEqual(self.filterset(params, self.queryset).qs.count(), 3) # 1 scoped + 1 global group + 1 global
|
||||
|
||||
def test_interface(self):
|
||||
interface_id = Interface.objects.first().pk
|
||||
params = {'interface_id': interface_id}
|
||||
|
|
|
|||
|
|
@ -29,19 +29,27 @@ class PrefixFormTestCase(TestCase):
|
|||
|
||||
assert form.fields['vlan'].widget.attrs['data-dynamic-params'] == self.default_dynamic_params
|
||||
|
||||
def test_vlan_field_sets_dynamic_params_for_scope_site_group(self):
|
||||
"""data-dynamic-params present with available_at_site_group when scope type is Site Group"""
|
||||
site_group = SiteGroup.objects.create(name='Site Group 1', slug='site-group-1')
|
||||
form = PrefixForm(data={
|
||||
'scope_type': ContentType.objects.get_for_model(SiteGroup).id,
|
||||
'scope': site_group,
|
||||
})
|
||||
expected = '[{"fieldName":"scope","queryParam":"available_at_site_group"}]'
|
||||
assert form.fields['vlan'].widget.attrs['data-dynamic-params'] == expected
|
||||
|
||||
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"""
|
||||
"""data-dynamic-params not present when scope type is not Site or Site Group"""
|
||||
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
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue