11from django import forms
2+ from django .contrib .contenttypes .models import ContentType
23from django .utils .translation import gettext_lazy as _
34
4- from dcim .models import Region , Site , SiteGroup
5+ from dcim .models import Location , Rack , Region , Site , SiteGroup
56from ipam .choices import *
67from ipam .constants import *
78from ipam .models import *
1011from tenancy .models import Tenant
1112from utilities .forms import add_blank_choice
1213from utilities .forms .fields import (
13- CommentField , DynamicModelChoiceField , DynamicModelMultipleChoiceField , NumericArrayField ,
14+ CommentField , ContentTypeChoiceField , DynamicModelChoiceField , DynamicModelMultipleChoiceField , NumericArrayField ,
1415)
1516from utilities .forms .widgets import BulkEditNullBooleanSelect
17+ from virtualization .models import Cluster , ClusterGroup
1618
1719__all__ = (
1820 'AggregateBulkEditForm' ,
@@ -407,11 +409,6 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
407409
408410
409411class VLANGroupBulkEditForm (NetBoxModelBulkEditForm ):
410- site = DynamicModelChoiceField (
411- label = _ ('Site' ),
412- queryset = Site .objects .all (),
413- required = False
414- )
415412 min_vid = forms .IntegerField (
416413 min_value = VLAN_VID_MIN ,
417414 max_value = VLAN_VID_MAX ,
@@ -429,12 +426,84 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
429426 max_length = 200 ,
430427 required = False
431428 )
429+ scope_type = ContentTypeChoiceField (
430+ label = _ ('Scope type' ),
431+ queryset = ContentType .objects .filter (model__in = VLANGROUP_SCOPE_TYPES ),
432+ required = False
433+ )
434+ scope_id = forms .IntegerField (
435+ required = False ,
436+ widget = forms .HiddenInput ()
437+ )
438+ region = DynamicModelChoiceField (
439+ label = _ ('Region' ),
440+ queryset = Region .objects .all (),
441+ required = False
442+ )
443+ sitegroup = DynamicModelChoiceField (
444+ queryset = SiteGroup .objects .all (),
445+ required = False ,
446+ label = _ ('Site group' )
447+ )
448+ site = DynamicModelChoiceField (
449+ label = _ ('Site' ),
450+ queryset = Site .objects .all (),
451+ required = False ,
452+ query_params = {
453+ 'region_id' : '$region' ,
454+ 'group_id' : '$sitegroup' ,
455+ }
456+ )
457+ location = DynamicModelChoiceField (
458+ label = _ ('Location' ),
459+ queryset = Location .objects .all (),
460+ required = False ,
461+ query_params = {
462+ 'site_id' : '$site' ,
463+ }
464+ )
465+ rack = DynamicModelChoiceField (
466+ label = _ ('Rack' ),
467+ queryset = Rack .objects .all (),
468+ required = False ,
469+ query_params = {
470+ 'site_id' : '$site' ,
471+ 'location_id' : '$location' ,
472+ }
473+ )
474+ clustergroup = DynamicModelChoiceField (
475+ queryset = ClusterGroup .objects .all (),
476+ required = False ,
477+ label = _ ('Cluster group' )
478+ )
479+ cluster = DynamicModelChoiceField (
480+ label = _ ('Cluster' ),
481+ queryset = Cluster .objects .all (),
482+ required = False ,
483+ query_params = {
484+ 'group_id' : '$clustergroup' ,
485+ }
486+ )
432487
433488 model = VLANGroup
434489 fieldsets = (
435490 (None , ('site' , 'min_vid' , 'max_vid' , 'description' )),
491+ (_ ('Scope' ), ('scope_type' , 'region' , 'sitegroup' , 'site' , 'location' , 'rack' , 'clustergroup' , 'cluster' )),
436492 )
437- nullable_fields = ('site' , 'description' )
493+ nullable_fields = ('description' ,)
494+
495+ def clean (self ):
496+ super ().clean ()
497+
498+ # Assign scope based on scope_type
499+ if self .cleaned_data .get ('scope_type' ):
500+ scope_field = self .cleaned_data ['scope_type' ].model
501+ if scope_obj := self .cleaned_data .get (scope_field ):
502+ self .cleaned_data ['scope_id' ] = scope_obj .pk
503+ self .changed_data .append ('scope_id' )
504+ else :
505+ self .cleaned_data .pop ('scope_type' )
506+ self .changed_data .remove ('scope_type' )
438507
439508
440509class VLANBulkEditForm (NetBoxModelBulkEditForm ):
0 commit comments