Browse Source

Added bulk tag addition/removal

Jeremy Stretch 7 years ago
parent
commit
208409110f

+ 3 - 3
netbox/circuits/forms.py

@@ -5,7 +5,7 @@ from django.db.models import Count
 from taggit.forms import TagField
 
 from dcim.models import Site, Device, Interface, Rack
-from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
+from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
 from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
@@ -55,7 +55,7 @@ class ProviderCSVForm(forms.ModelForm):
         }
 
 
-class ProviderBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class ProviderBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Provider.objects.all(), widget=forms.MultipleHiddenInput)
     asn = forms.IntegerField(required=False, label='ASN')
     account = forms.CharField(max_length=30, required=False, label='Account number')
@@ -158,7 +158,7 @@ class CircuitCSVForm(forms.ModelForm):
         ]
 
 
-class CircuitBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class CircuitBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     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)

+ 5 - 5
netbox/dcim/forms.py

@@ -10,7 +10,7 @@ from mptt.forms import TreeNodeChoiceField
 from taggit.forms import TagField
 from timezone_field import TimeZoneFormField
 
-from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
+from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
 from ipam.models import IPAddress, VLAN, VLANGroup
 from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
@@ -170,7 +170,7 @@ class SiteCSVForm(forms.ModelForm):
         }
 
 
-class SiteBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class SiteBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(
         queryset=Site.objects.all(),
         widget=forms.MultipleHiddenInput
@@ -403,7 +403,7 @@ class RackCSVForm(forms.ModelForm):
                 )
 
 
-class RackBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class RackBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Rack.objects.all(), widget=forms.MultipleHiddenInput)
     site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False, label='Site')
     group = forms.ModelChoiceField(queryset=RackGroup.objects.all(), required=False, label='Group')
@@ -572,7 +572,7 @@ class DeviceTypeCSVForm(forms.ModelForm):
         }
 
 
-class DeviceTypeBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class DeviceTypeBulkEditForm(BootstrapMixin, AddRemoveTagsForm, 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)
@@ -1090,7 +1090,7 @@ class ChildDeviceCSVForm(BaseDeviceCSVForm):
                 raise forms.ValidationError("Parent device/bay ({} {}) not found".format(parent, device_bay_name))
 
 
-class DeviceBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class DeviceBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     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')

+ 11 - 0
netbox/extras/forms.py

@@ -7,6 +7,7 @@ from django.contrib.auth.models import User
 from django.contrib.contenttypes.models import ContentType
 from django.core.exceptions import ObjectDoesNotExist
 from mptt.forms import TreeNodeMultipleChoiceField
+from taggit.forms import TagField
 from taggit.models import Tag
 
 from dcim.models import Region
@@ -193,6 +194,16 @@ class TagForm(BootstrapMixin, forms.ModelForm):
         fields = ['name', 'slug']
 
 
+class AddRemoveTagsForm(forms.Form):
+
+    def __init__(self, *args, **kwargs):
+        super(AddRemoveTagsForm, self).__init__(*args, **kwargs)
+
+        # Add add/remove tags fields
+        self.fields['add_tags'] = TagField(required=False)
+        self.fields['remove_tags'] = TagField(required=False)
+
+
 #
 # Config contexts
 #

+ 6 - 6
netbox/ipam/forms.py

@@ -7,7 +7,7 @@ from django.db.models import Count
 from taggit.forms import TagField
 
 from dcim.models import Site, Rack, Device, Interface
-from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
+from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
 from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
 from utilities.forms import (
@@ -68,7 +68,7 @@ class VRFCSVForm(forms.ModelForm):
         }
 
 
-class VRFBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class VRFBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=VRF.objects.all(), widget=forms.MultipleHiddenInput)
     tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False)
     enforce_unique = forms.NullBooleanField(
@@ -153,7 +153,7 @@ class AggregateCSVForm(forms.ModelForm):
         fields = Aggregate.csv_headers
 
 
-class AggregateBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class AggregateBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Aggregate.objects.all(), widget=forms.MultipleHiddenInput)
     rir = forms.ModelChoiceField(queryset=RIR.objects.all(), required=False, label='RIR')
     date_added = forms.DateField(required=False)
@@ -346,7 +346,7 @@ class PrefixCSVForm(forms.ModelForm):
                 raise forms.ValidationError("Multiple VLANs with VID {} found".format(vlan_vid))
 
 
-class PrefixBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class PrefixBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Prefix.objects.all(), widget=forms.MultipleHiddenInput)
     site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False)
     vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF')
@@ -678,7 +678,7 @@ class IPAddressCSVForm(forms.ModelForm):
         return ipaddress
 
 
-class IPAddressBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class IPAddressBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=IPAddress.objects.all(), widget=forms.MultipleHiddenInput)
     vrf = forms.ModelChoiceField(queryset=VRF.objects.all(), required=False, label='VRF')
     tenant = forms.ModelChoiceField(queryset=Tenant.objects.all(), required=False)
@@ -869,7 +869,7 @@ class VLANCSVForm(forms.ModelForm):
                     raise forms.ValidationError("Global VLAN group {} not found".format(group_name))
 
 
-class VLANBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class VLANBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=VLAN.objects.all(), widget=forms.MultipleHiddenInput)
     site = forms.ModelChoiceField(queryset=Site.objects.all(), required=False)
     group = forms.ModelChoiceField(queryset=VLANGroup.objects.all(), required=False)

+ 2 - 1
netbox/secrets/forms.py

@@ -7,6 +7,7 @@ from django.db.models import Count
 from taggit.forms import TagField
 
 from dcim.models import Device
+from extras.forms import AddRemoveTagsForm
 from utilities.forms import BootstrapMixin, BulkEditForm, FilterChoiceField, FlexibleModelChoiceField, SlugField
 from .models import Secret, SecretRole, UserKey
 
@@ -128,7 +129,7 @@ class SecretCSVForm(forms.ModelForm):
         return s
 
 
-class SecretBulkEditForm(BootstrapMixin, BulkEditForm):
+class SecretBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Secret.objects.all(), widget=forms.MultipleHiddenInput)
     role = forms.ModelChoiceField(queryset=SecretRole.objects.all(), required=False)
     name = forms.CharField(max_length=100, required=False)

+ 2 - 2
netbox/tenancy/forms.py

@@ -4,7 +4,7 @@ from django import forms
 from django.db.models import Count
 from taggit.forms import TagField
 
-from extras.forms import CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
+from extras.forms import AddRemoveTagsForm, CustomFieldForm, CustomFieldBulkEditForm, CustomFieldFilterForm
 from utilities.forms import (
     APISelect, BootstrapMixin, ChainedFieldsMixin, ChainedModelChoiceField, CommentField, FilterChoiceField, SlugField,
 )
@@ -69,7 +69,7 @@ class TenantCSVForm(forms.ModelForm):
         }
 
 
-class TenantBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class TenantBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Tenant.objects.all(), widget=forms.MultipleHiddenInput)
     group = forms.ModelChoiceField(queryset=TenantGroup.objects.all(), required=False)
 

+ 6 - 0
netbox/utilities/views.py

@@ -543,6 +543,12 @@ class BulkEditView(GetReturnURLMixin, View):
                                     cfv.value = form.cleaned_data[name]
                                     cfv.save()
 
+                            # Add/remove tags
+                            if form.cleaned_data.get('add_tags', None):
+                                obj.tags.add(*form.cleaned_data['add_tags'])
+                            if form.cleaned_data.get('remove_tags', None):
+                                obj.tags.remove(*form.cleaned_data['remove_tags'])
+
                             updated_count += 1
 
                     if updated_count:

+ 3 - 3
netbox/virtualization/forms.py

@@ -10,7 +10,7 @@ from dcim.constants import IFACE_FF_VIRTUAL, IFACE_MODE_ACCESS, IFACE_MODE_TAGGE
 from dcim.forms import INTERFACE_MODE_HELP_TEXT
 from dcim.formfields import MACAddressFormField
 from dcim.models import Device, DeviceRole, Interface, Platform, Rack, Region, Site
-from extras.forms import CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm
+from extras.forms import AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldForm, CustomFieldFilterForm
 from ipam.models import IPAddress
 from tenancy.forms import TenancyForm
 from tenancy.models import Tenant
@@ -119,7 +119,7 @@ class ClusterCSVForm(forms.ModelForm):
         fields = Cluster.csv_headers
 
 
-class ClusterBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class ClusterBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=Cluster.objects.all(), widget=forms.MultipleHiddenInput)
     type = forms.ModelChoiceField(queryset=ClusterType.objects.all(), required=False)
     group = forms.ModelChoiceField(queryset=ClusterGroup.objects.all(), required=False)
@@ -349,7 +349,7 @@ class VirtualMachineCSVForm(forms.ModelForm):
         fields = VirtualMachine.csv_headers
 
 
-class VirtualMachineBulkEditForm(BootstrapMixin, CustomFieldBulkEditForm):
+class VirtualMachineBulkEditForm(BootstrapMixin, AddRemoveTagsForm, CustomFieldBulkEditForm):
     pk = forms.ModelMultipleChoiceField(queryset=VirtualMachine.objects.all(), widget=forms.MultipleHiddenInput)
     status = forms.ChoiceField(choices=add_blank_choice(VM_STATUS_CHOICES), required=False, initial='')
     cluster = forms.ModelChoiceField(queryset=Cluster.objects.all(), required=False)