diff --git a/netbox/circuits/forms.py b/netbox/circuits/forms.py index d5535ef53..b5152e08c 100644 --- a/netbox/circuits/forms.py +++ b/netbox/circuits/forms.py @@ -2,6 +2,7 @@ from django import forms from django.db.models import Count from dcim.models import Site, Device, Interface, Rack, IFACE_FF_VIRTUAL +from tenancy.forms import bulkedit_tenant_choices from tenancy.models import Tenant from utilities.forms import ( APISelect, BootstrapMixin, BulkImportForm, CommentField, CSVDataField, Livesearch, SmallTextarea, SlugField, @@ -180,7 +181,7 @@ class CircuitBulkEditForm(forms.Form, BootstrapMixin): pk = forms.ModelMultipleChoiceField(queryset=Circuit.objects.all(), widget=forms.MultipleHiddenInput) type = forms.ModelChoiceField(queryset=CircuitType.objects.all(), required=False) provider = forms.ModelChoiceField(queryset=Provider.objects.all(), required=False) - tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False) + tenant = forms.TypedChoiceField(choices=bulkedit_tenant_choices, coerce=int, required=False, label='Tenant') port_speed = forms.IntegerField(required=False, label='Port speed (Kbps)') commit_rate = forms.IntegerField(required=False, label='Commit rate (Kbps)') comments = CommentField() diff --git a/netbox/circuits/views.py b/netbox/circuits/views.py index 3076a9141..381670d89 100644 --- a/netbox/circuits/views.py +++ b/netbox/circuits/views.py @@ -159,7 +159,11 @@ class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - for field in ['type', 'provider', 'tenant', 'port_speed', 'commit_rate', 'comments']: + if form.cleaned_data['tenant'] == 0: + fields_to_update['tenant'] = None + elif form.cleaned_data['tenant']: + fields_to_update['tenant'] = form.cleaned_data['tenant'] + for field in ['type', 'provider', 'port_speed', 'commit_rate', 'comments']: if form.cleaned_data[field]: fields_to_update[field] = form.cleaned_data[field] diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 244952885..fef87ded0 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -4,6 +4,7 @@ from django import forms from django.db.models import Count, Q from ipam.models import IPAddress +from tenancy.forms import bulkedit_tenant_choices from tenancy.models import Tenant from utilities.forms import ( APISelect, BootstrapMixin, BulkImportForm, CommentField, CSVDataField, ExpandableNameField, @@ -39,6 +40,15 @@ def get_device_by_name_or_pk(name): return device +def bulkedit_platform_choices(): + choices = [ + (None, '---------'), + (0, 'None'), + ] + choices += [(p.pk, p.name) for p in Platform.objects.all()] + return choices + + # # Sites # @@ -78,7 +88,7 @@ class SiteImportForm(BulkImportForm, BootstrapMixin): class SiteBulkEditForm(forms.Form, BootstrapMixin): pk = forms.ModelMultipleChoiceField(queryset=Site.objects.all(), widget=forms.MultipleHiddenInput) - tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False) + tenant = forms.TypedChoiceField(choices=bulkedit_tenant_choices, coerce=int, required=False, label='Tenant') def site_tenant_choices(): @@ -181,7 +191,7 @@ class RackBulkEditForm(forms.Form, BootstrapMixin): pk = forms.ModelMultipleChoiceField(queryset=Rack.objects.all(), widget=forms.MultipleHiddenInput) site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False) group = forms.ModelChoiceField(queryset=RackGroup.objects.all(), required=False) - tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False) + tenant = forms.TypedChoiceField(choices=bulkedit_tenant_choices, coerce=int, required=False, label='Tenant') u_height = forms.IntegerField(required=False, label='Height (U)') comments = CommentField() @@ -538,21 +548,12 @@ class ChildDeviceImportForm(BulkImportForm, BootstrapMixin): csv = CSVDataField(csv_form=ChildDeviceFromCSVForm) -def device_edit_platform_choices(): - choices = [ - (None, '---------'), - (0, 'None'), - ] - choices += [(p.pk, p.name) for p in Platform.objects.all()] - return choices - - class DeviceBulkEditForm(forms.Form, BootstrapMixin): pk = forms.ModelMultipleChoiceField(queryset=Device.objects.all(), widget=forms.MultipleHiddenInput) device_type = forms.ModelChoiceField(queryset=DeviceType.objects.all(), required=False, label='Type') device_role = forms.ModelChoiceField(queryset=DeviceRole.objects.all(), required=False, label='Role') - tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False, label='Tenant') - platform = forms.TypedChoiceField(choices=device_edit_platform_choices, coerce=int, required=False, + tenant = forms.TypedChoiceField(choices=bulkedit_tenant_choices, coerce=int, required=False, label='Tenant') + platform = forms.TypedChoiceField(choices=bulkedit_platform_choices, coerce=int, required=False, label='Platform') status = forms.ChoiceField(choices=FORM_STATUS_CHOICES, required=False, initial='', label='Status') serial = forms.CharField(max_length=50, required=False, label='Serial Number') diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 3f22bca85..f0b3ce55a 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -122,9 +122,10 @@ class SiteBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - for field in ['tenant']: - if form.cleaned_data[field]: - fields_to_update[field] = form.cleaned_data[field] + if form.cleaned_data['tenant'] == 0: + fields_to_update['tenant'] = None + elif form.cleaned_data['tenant']: + fields_to_update['tenant'] = form.cleaned_data['tenant'] return self.cls.objects.filter(pk__in=pk_list).update(**fields_to_update) @@ -220,6 +221,10 @@ class RackBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} + if form.cleaned_data['tenant'] == 0: + fields_to_update['tenant'] = None + elif form.cleaned_data['tenant']: + fields_to_update['tenant'] = form.cleaned_data['tenant'] for field in ['site', 'group', 'tenant', 'u_height', 'comments']: if form.cleaned_data[field]: fields_to_update[field] = form.cleaned_data[field] @@ -645,10 +650,11 @@ class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - if form.cleaned_data['platform'] == 0: - fields_to_update['platform'] = None - elif form.cleaned_data['platform']: - fields_to_update['platform'] = form.cleaned_data['platform'] + for field in ['tenant', 'platform']: + if form.cleaned_data[field] == 0: + fields_to_update[field] = None + elif form.cleaned_data[field]: + fields_to_update[field] = form.cleaned_data[field] if form.cleaned_data['status']: status = form.cleaned_data['status'] fields_to_update['status'] = True if status == 'True' else False diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 2a2c5413b..0449efdb2 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -4,6 +4,7 @@ from django import forms from django.db.models import Count from dcim.models import Site, Device, Interface +from tenancy.forms import bulkedit_tenant_choices from tenancy.models import Tenant from utilities.forms import BootstrapMixin, APISelect, Livesearch, CSVDataField, BulkImportForm, SlugField @@ -17,6 +18,9 @@ FORM_VLAN_STATUS_CHOICES = (('', '---------'),) + VLAN_STATUS_CHOICES def bulkedit_vrf_choices(): + """ + Include an option to assign the object to the global table. + """ choices = [ (None, '---------'), (0, 'Global'), @@ -25,15 +29,6 @@ def bulkedit_vrf_choices(): return choices -def bulkedit_tenant_choices(): - choices = [ - (None, '---------'), - (0, 'None'), - ] - choices += [(t.pk, t.name) for t in Tenant.objects.all()] - return choices - - # # VRFs # diff --git a/netbox/ipam/views.py b/netbox/ipam/views.py index 7402247b8..b99438a02 100644 --- a/netbox/ipam/views.py +++ b/netbox/ipam/views.py @@ -86,7 +86,11 @@ class VRFBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - for field in ['tenant', 'description']: + if form.cleaned_data['tenant'] == 0: + fields_to_update['tenant'] = None + elif form.cleaned_data['tenant']: + fields_to_update['tenant'] = form.cleaned_data['tenant'] + for field in ['description']: if form.cleaned_data[field]: fields_to_update[field] = form.cleaned_data[field] @@ -338,10 +342,11 @@ class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - if form.cleaned_data['vrf'] == 0: - fields_to_update['vrf'] = None - elif form.cleaned_data['vrf']: - fields_to_update['vrf'] = form.cleaned_data['vrf'] + for field in ['vrf', 'tenant']: + if form.cleaned_data[field] == 0: + fields_to_update[field] = None + elif form.cleaned_data[field]: + fields_to_update[field] = form.cleaned_data[field] for field in ['site', 'status', 'role', 'description']: if form.cleaned_data[field]: fields_to_update[field] = form.cleaned_data[field] @@ -462,10 +467,11 @@ class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - if form.cleaned_data['vrf'] == 0: - fields_to_update['vrf'] = None - elif form.cleaned_data['vrf']: - fields_to_update['vrf'] = form.cleaned_data['vrf'] + for field in ['vrf', 'tenant']: + if form.cleaned_data[field] == 0: + fields_to_update[field] = None + elif form.cleaned_data[field]: + fields_to_update[field] = form.cleaned_data[field] for field in ['description']: if form.cleaned_data[field]: fields_to_update[field] = form.cleaned_data[field] @@ -560,7 +566,11 @@ class VLANBulkEditView(PermissionRequiredMixin, BulkEditView): def update_objects(self, pk_list, form): fields_to_update = {} - for field in ['site', 'group', 'tenant', 'status', 'role', 'description']: + if form.cleaned_data['tenant'] == 0: + fields_to_update['tenant'] = None + elif form.cleaned_data['tenant']: + fields_to_update['tenant'] = form.cleaned_data['tenant'] + for field in ['site', 'group', 'status', 'role', 'description']: if form.cleaned_data[field]: fields_to_update[field] = form.cleaned_data[field] diff --git a/netbox/tenancy/forms.py b/netbox/tenancy/forms.py index 14ffe7ef4..bf04454ba 100644 --- a/netbox/tenancy/forms.py +++ b/netbox/tenancy/forms.py @@ -8,6 +8,18 @@ from utilities.forms import ( from .models import Tenant, TenantGroup +def bulkedit_tenant_choices(): + """ + Include an option to remove the currently assigned Tenant from an object. + """ + choices = [ + (None, '---------'), + (0, 'None'), + ] + choices += [(t.pk, t.name) for t in Tenant.objects.all()] + return choices + + # # Tenant groups #