mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-22 20:12:00 -06:00
Closes #1110: Expand bulk edit forms to include boolean fields (e.g. toggle is_pool for prefixes)
This commit is contained in:
parent
e7a6d1f532
commit
aea5612c39
@ -11,9 +11,9 @@ from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFi
|
||||
from ipam.models import IPAddress
|
||||
from tenancy.models import Tenant
|
||||
from utilities.forms import (
|
||||
APISelect, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, BulkImportForm, CommentField,
|
||||
CSVDataField, ExpandableNameField, FilterChoiceField, FlexibleModelChoiceField, Livesearch, SelectWithDisabled,
|
||||
SmallTextarea, SlugField, FilterTreeNodeMultipleChoiceField,
|
||||
APISelect, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
|
||||
BulkImportForm, CommentField, CSVDataField, ExpandableNameField, FilterChoiceField, FlexibleModelChoiceField,
|
||||
Livesearch, SelectWithDisabled, SmallTextarea, SlugField, FilterTreeNodeMultipleChoiceField,
|
||||
)
|
||||
|
||||
from .formfields import MACAddressFormField
|
||||
@ -272,6 +272,7 @@ class RackBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
type = forms.ChoiceField(choices=add_blank_choice(RACK_TYPE_CHOICES), required=False, label='Type')
|
||||
width = forms.ChoiceField(choices=add_blank_choice(RACK_WIDTH_CHOICES), required=False, label='Width')
|
||||
u_height = forms.IntegerField(required=False, label='Height (U)')
|
||||
desc_units = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Descending units')
|
||||
comments = CommentField(widget=SmallTextarea)
|
||||
|
||||
class Meta:
|
||||
@ -375,7 +376,13 @@ class DeviceTypeBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(queryset=DeviceType.objects.all(), widget=forms.MultipleHiddenInput)
|
||||
manufacturer = forms.ModelChoiceField(queryset=Manufacturer.objects.all(), required=False)
|
||||
u_height = forms.IntegerField(min_value=1, required=False)
|
||||
is_full_depth = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Is full depth')
|
||||
interface_ordering = forms.ChoiceField(choices=add_blank_choice(IFACE_ORDERING_CHOICES), required=False)
|
||||
is_console_server = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Is full depth')
|
||||
is_pdu = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Is a PDU')
|
||||
is_network_device = forms.NullBooleanField(
|
||||
required=False, widget=BulkEditNullBooleanSelect, label='Is a network device'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
nullable_fields = []
|
||||
@ -484,6 +491,7 @@ class InterfaceTemplateCreateForm(DeviceComponentForm):
|
||||
class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(queryset=InterfaceTemplate.objects.all(), widget=forms.MultipleHiddenInput)
|
||||
form_factor = forms.ChoiceField(choices=add_blank_choice(IFACE_FF_CHOICES), required=False)
|
||||
mgmt_only = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Management only')
|
||||
|
||||
class Meta:
|
||||
nullable_fields = []
|
||||
@ -1413,6 +1421,7 @@ class InterfaceBulkEditForm(BootstrapMixin, BulkEditForm):
|
||||
device = forms.ModelChoiceField(queryset=Device.objects.all(), widget=forms.HiddenInput)
|
||||
lag = forms.ModelChoiceField(queryset=Interface.objects.all(), required=False, label='Parent LAG')
|
||||
form_factor = forms.ChoiceField(choices=add_blank_choice(IFACE_FF_CHOICES), required=False)
|
||||
mgmt_only = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Management only')
|
||||
description = forms.CharField(max_length=100, required=False)
|
||||
|
||||
class Meta:
|
||||
|
@ -5,8 +5,8 @@ from dcim.models import Site, Rack, Device, Interface
|
||||
from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
|
||||
from tenancy.models import Tenant
|
||||
from utilities.forms import (
|
||||
APISelect, BootstrapMixin, BulkImportForm, CSVDataField, ExpandableIPAddressField, FilterChoiceField, Livesearch,
|
||||
ReturnURLForm, SlugField, add_blank_choice,
|
||||
APISelect, BootstrapMixin, BulkEditNullBooleanSelect, BulkImportForm, CSVDataField, ExpandableIPAddressField,
|
||||
FilterChoiceField, Livesearch, ReturnURLForm, SlugField, add_blank_choice,
|
||||
)
|
||||
|
||||
from .models import (
|
||||
@ -61,6 +61,9 @@ class VRFImportForm(BootstrapMixin, BulkImportForm):
|
||||
class VRFBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
pk = forms.ModelMultipleChoiceField(queryset=VRF.objects.all(), widget=forms.MultipleHiddenInput)
|
||||
tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False)
|
||||
enforce_unique = forms.NullBooleanField(
|
||||
required=False, widget=BulkEditNullBooleanSelect, label='Enforce unique space'
|
||||
)
|
||||
description = forms.CharField(max_length=100, required=False)
|
||||
|
||||
class Meta:
|
||||
@ -256,6 +259,7 @@ class PrefixBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
|
||||
tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False)
|
||||
status = forms.ChoiceField(choices=add_blank_choice(PREFIX_STATUS_CHOICES), required=False)
|
||||
role = forms.ModelChoiceField(queryset=Role.objects.all(), required=False)
|
||||
is_pool = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label='Is a pool')
|
||||
description = forms.CharField(max_length=100, required=False)
|
||||
|
||||
class Meta:
|
||||
|
@ -138,6 +138,19 @@ class ColorSelect(forms.Select):
|
||||
option_value, selected_html, option_value, force_text(option_label))
|
||||
|
||||
|
||||
class BulkEditNullBooleanSelect(forms.NullBooleanSelect):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(BulkEditNullBooleanSelect, self).__init__(*args, **kwargs)
|
||||
|
||||
# Override the built-in choice labels
|
||||
self.choices = (
|
||||
('1', '---------'),
|
||||
('2', 'Yes'),
|
||||
('3', 'No'),
|
||||
)
|
||||
|
||||
|
||||
class SelectWithDisabled(forms.Select):
|
||||
"""
|
||||
Modified the stock Select widget to accept choices using a dict() for a label. The dict for each option must include
|
||||
|
@ -423,7 +423,7 @@ class BulkEditView(View):
|
||||
filter: FilterSet to apply when deleting by QuerySet
|
||||
form: The form class used to edit objects in bulk
|
||||
template_name: The name of the template
|
||||
default_return_url: Name of the URL to which the user is redirected after editing the objects (can be overriden by
|
||||
default_return_url: Name of the URL to which the user is redirected after editing the objects (can be overridden by
|
||||
POSTing return_url)
|
||||
"""
|
||||
cls = None
|
||||
@ -475,7 +475,7 @@ class BulkEditView(View):
|
||||
fields_to_update[field] = ''
|
||||
else:
|
||||
fields_to_update[field] = None
|
||||
elif form.cleaned_data[field]:
|
||||
elif form.cleaned_data[field] not in (None, ''):
|
||||
fields_to_update[field] = form.cleaned_data[field]
|
||||
updated_count = self.cls.objects.filter(pk__in=pk_list).update(**fields_to_update)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user