mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-17 04:32:51 -06:00
* Update VLANGroup bulk edit form to support all scope types * Fixes #13843: Fix scope assignment for VLAN groups during bulk edit * Add missed static file * Restore graphiql static assets
This commit is contained in:
parent
b759d694ee
commit
1ad6d94dc3
@ -1,7 +1,8 @@
|
|||||||
from django import forms
|
from django import forms
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from dcim.models import Region, Site, SiteGroup
|
from dcim.models import Location, Rack, Region, Site, SiteGroup
|
||||||
from ipam.choices import *
|
from ipam.choices import *
|
||||||
from ipam.constants import *
|
from ipam.constants import *
|
||||||
from ipam.models import *
|
from ipam.models import *
|
||||||
@ -10,9 +11,10 @@ from netbox.forms import NetBoxModelBulkEditForm
|
|||||||
from tenancy.models import Tenant
|
from tenancy.models import Tenant
|
||||||
from utilities.forms import add_blank_choice
|
from utilities.forms import add_blank_choice
|
||||||
from utilities.forms.fields import (
|
from utilities.forms.fields import (
|
||||||
CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, NumericArrayField,
|
CommentField, ContentTypeChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField, NumericArrayField,
|
||||||
)
|
)
|
||||||
from utilities.forms.widgets import BulkEditNullBooleanSelect
|
from utilities.forms.widgets import BulkEditNullBooleanSelect
|
||||||
|
from virtualization.models import Cluster, ClusterGroup
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
'AggregateBulkEditForm',
|
'AggregateBulkEditForm',
|
||||||
@ -407,11 +409,6 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
|
|
||||||
|
|
||||||
class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
|
class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
site = DynamicModelChoiceField(
|
|
||||||
label=_('Site'),
|
|
||||||
queryset=Site.objects.all(),
|
|
||||||
required=False
|
|
||||||
)
|
|
||||||
min_vid = forms.IntegerField(
|
min_vid = forms.IntegerField(
|
||||||
min_value=VLAN_VID_MIN,
|
min_value=VLAN_VID_MIN,
|
||||||
max_value=VLAN_VID_MAX,
|
max_value=VLAN_VID_MAX,
|
||||||
@ -429,12 +426,84 @@ class VLANGroupBulkEditForm(NetBoxModelBulkEditForm):
|
|||||||
max_length=200,
|
max_length=200,
|
||||||
required=False
|
required=False
|
||||||
)
|
)
|
||||||
|
scope_type = ContentTypeChoiceField(
|
||||||
|
label=_('Scope type'),
|
||||||
|
queryset=ContentType.objects.filter(model__in=VLANGROUP_SCOPE_TYPES),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
scope_id = forms.IntegerField(
|
||||||
|
required=False,
|
||||||
|
widget=forms.HiddenInput()
|
||||||
|
)
|
||||||
|
region = DynamicModelChoiceField(
|
||||||
|
label=_('Region'),
|
||||||
|
queryset=Region.objects.all(),
|
||||||
|
required=False
|
||||||
|
)
|
||||||
|
sitegroup = DynamicModelChoiceField(
|
||||||
|
queryset=SiteGroup.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Site group')
|
||||||
|
)
|
||||||
|
site = DynamicModelChoiceField(
|
||||||
|
label=_('Site'),
|
||||||
|
queryset=Site.objects.all(),
|
||||||
|
required=False,
|
||||||
|
query_params={
|
||||||
|
'region_id': '$region',
|
||||||
|
'group_id': '$sitegroup',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
location = DynamicModelChoiceField(
|
||||||
|
label=_('Location'),
|
||||||
|
queryset=Location.objects.all(),
|
||||||
|
required=False,
|
||||||
|
query_params={
|
||||||
|
'site_id': '$site',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
rack = DynamicModelChoiceField(
|
||||||
|
label=_('Rack'),
|
||||||
|
queryset=Rack.objects.all(),
|
||||||
|
required=False,
|
||||||
|
query_params={
|
||||||
|
'site_id': '$site',
|
||||||
|
'location_id': '$location',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
clustergroup = DynamicModelChoiceField(
|
||||||
|
queryset=ClusterGroup.objects.all(),
|
||||||
|
required=False,
|
||||||
|
label=_('Cluster group')
|
||||||
|
)
|
||||||
|
cluster = DynamicModelChoiceField(
|
||||||
|
label=_('Cluster'),
|
||||||
|
queryset=Cluster.objects.all(),
|
||||||
|
required=False,
|
||||||
|
query_params={
|
||||||
|
'group_id': '$clustergroup',
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
model = VLANGroup
|
model = VLANGroup
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
(None, ('site', 'min_vid', 'max_vid', 'description')),
|
(None, ('site', 'min_vid', 'max_vid', 'description')),
|
||||||
|
(_('Scope'), ('scope_type', 'region', 'sitegroup', 'site', 'location', 'rack', 'clustergroup', 'cluster')),
|
||||||
)
|
)
|
||||||
nullable_fields = ('site', 'description')
|
nullable_fields = ('description',)
|
||||||
|
|
||||||
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
|
||||||
|
# Assign scope based on scope_type
|
||||||
|
if self.cleaned_data.get('scope_type'):
|
||||||
|
scope_field = self.cleaned_data['scope_type'].model
|
||||||
|
if scope_obj := self.cleaned_data.get(scope_field):
|
||||||
|
self.cleaned_data['scope_id'] = scope_obj.pk
|
||||||
|
self.changed_data.append('scope_id')
|
||||||
|
else:
|
||||||
|
self.cleaned_data.pop('scope_type')
|
||||||
|
self.changed_data.remove('scope_type')
|
||||||
|
|
||||||
|
|
||||||
class VLANBulkEditForm(NetBoxModelBulkEditForm):
|
class VLANBulkEditForm(NetBoxModelBulkEditForm):
|
||||||
|
@ -3,6 +3,7 @@ import re
|
|||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.contenttypes.fields import GenericRel
|
||||||
from django.contrib.contenttypes.models import ContentType
|
from django.contrib.contenttypes.models import ContentType
|
||||||
from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
|
from django.core.exceptions import FieldDoesNotExist, ObjectDoesNotExist, ValidationError
|
||||||
from django.db import transaction, IntegrityError
|
from django.db import transaction, IntegrityError
|
||||||
@ -519,9 +520,11 @@ class BulkEditView(GetReturnURLMixin, BaseMultiObjectView):
|
|||||||
model_field = self.queryset.model._meta.get_field(name)
|
model_field = self.queryset.model._meta.get_field(name)
|
||||||
if isinstance(model_field, (ManyToManyField, ManyToManyRel)):
|
if isinstance(model_field, (ManyToManyField, ManyToManyRel)):
|
||||||
m2m_fields[name] = model_field
|
m2m_fields[name] = model_field
|
||||||
|
elif isinstance(model_field, GenericRel):
|
||||||
|
# Ignore generic relations (these may be used for other purposes in the form)
|
||||||
|
continue
|
||||||
else:
|
else:
|
||||||
model_fields[name] = model_field
|
model_fields[name] = model_field
|
||||||
|
|
||||||
except FieldDoesNotExist:
|
except FieldDoesNotExist:
|
||||||
# This form field is used to modify a field rather than set its value directly
|
# This form field is used to modify a field rather than set its value directly
|
||||||
model_fields[name] = None
|
model_fields[name] = None
|
||||||
|
BIN
netbox/project-static/dist/netbox.js
vendored
BIN
netbox/project-static/dist/netbox.js
vendored
Binary file not shown.
BIN
netbox/project-static/dist/netbox.js.map
vendored
BIN
netbox/project-static/dist/netbox.js.map
vendored
Binary file not shown.
@ -88,6 +88,7 @@ const showHideLayout: ShowHideLayout = {
|
|||||||
const showHideMap: ShowHideMap = {
|
const showHideMap: ShowHideMap = {
|
||||||
vlangroup_add: 'vlangroup',
|
vlangroup_add: 'vlangroup',
|
||||||
vlangroup_edit: 'vlangroup',
|
vlangroup_edit: 'vlangroup',
|
||||||
|
vlangroup_bulk_edit: 'vlangroup',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user