Просмотр исходного кода

Fix tag assignment when bulk creating components

Jeremy Stretch 5 лет назад
Родитель
Сommit
7b50f2b0eb
3 измененных файлов с 41 добавлено и 41 удалено
  1. 12 21
      netbox/dcim/forms.py
  2. 24 17
      netbox/utilities/views.py
  3. 5 3
      netbox/virtualization/forms.py

+ 12 - 21
netbox/dcim/forms.py

@@ -2299,6 +2299,11 @@ class DeviceBulkAddComponentForm(BootstrapMixin, forms.Form):
         label='Name'
     )
 
+    def clean_tags(self):
+        # Because we're feeding TagField data (on the bulk edit form) to another TagField (on the model form), we
+        # must first convert the list of tags to a string.
+        return ','.join(self.cleaned_data.get('tags'))
+
 
 #
 # Console ports
@@ -2355,9 +2360,7 @@ class ConsolePortBulkCreateForm(
     form_from_model(ConsolePort, ['type', 'description', 'tags']),
     DeviceBulkAddComponentForm
 ):
-    tags = TagField(
-        required=False
-    )
+    pass
 
 
 class ConsolePortBulkEditForm(
@@ -2447,9 +2450,7 @@ class ConsoleServerPortBulkCreateForm(
     form_from_model(ConsoleServerPort, ['type', 'description', 'tags']),
     DeviceBulkAddComponentForm
 ):
-    tags = TagField(
-        required=False
-    )
+    pass
 
 
 class ConsoleServerPortBulkEditForm(
@@ -2563,9 +2564,7 @@ class PowerPortBulkCreateForm(
     form_from_model(PowerPort, ['type', 'maximum_draw', 'allocated_draw', 'description', 'tags']),
     DeviceBulkAddComponentForm
 ):
-    tags = TagField(
-        required=False
-    )
+    pass
 
 
 class PowerPortBulkEditForm(
@@ -2685,9 +2684,7 @@ class PowerOutletBulkCreateForm(
     form_from_model(PowerOutlet, ['type', 'feed_leg', 'description', 'tags']),
     DeviceBulkAddComponentForm
 ):
-    tags = TagField(
-        required=False
-    )
+    pass
 
 
 class PowerOutletBulkEditForm(
@@ -2968,9 +2965,7 @@ class InterfaceBulkCreateForm(
     form_from_model(Interface, ['type', 'enabled', 'mtu', 'mgmt_only', 'description', 'tags']),
     DeviceBulkAddComponentForm
 ):
-    tags = TagField(
-        required=False
-    )
+    pass
 
 
 class InterfaceBulkEditForm(
@@ -3241,9 +3236,7 @@ class FrontPortCreateForm(BootstrapMixin, forms.Form):
 #     form_from_model(FrontPort, ['type', 'description', 'tags']),
 #     DeviceBulkAddComponentForm
 # ):
-#     tags = TagField(
-#         required=False
-#     )
+#     pass
 
 
 class FrontPortBulkEditForm(
@@ -3381,9 +3374,7 @@ class RearPortBulkCreateForm(
     form_from_model(RearPort, ['type', 'positions', 'description', 'tags']),
     DeviceBulkAddComponentForm
 ):
-    tags = TagField(
-        required=False
-    )
+    pass
 
 
 class RearPortBulkEditForm(

+ 24 - 17
netbox/utilities/views.py

@@ -972,25 +972,32 @@ class BulkComponentCreateView(GetReturnURLMixin, View):
                 new_components = []
                 data = deepcopy(form.cleaned_data)
 
-                for obj in data['pk']:
-
-                    names = data['name_pattern']
-                    for name in names:
-                        component_data = {
-                            self.parent_field: obj.pk,
-                            'name': name,
-                        }
-                        component_data.update(data)
-                        component_form = self.model_form(component_data)
-                        if component_form.is_valid():
-                            new_components.append(component_form.save(commit=False))
-                        else:
-                            for field, errors in component_form.errors.as_data().items():
-                                for e in errors:
-                                    form.add_error(field, '{} {}: {}'.format(obj, name, ', '.join(e)))
+                try:
+                    with transaction.atomic():
+
+                        for obj in data['pk']:
+
+                            names = data['name_pattern']
+                            for name in names:
+                                component_data = {
+                                    self.parent_field: obj.pk,
+                                    'name': name,
+                                }
+                                component_data.update(data)
+                                component_form = self.model_form(component_data)
+                                if component_form.is_valid():
+                                    instance = component_form.save()
+                                    logger.debug(f"Created {instance} on {instance.parent}")
+                                    new_components.append(instance)
+                                else:
+                                    for field, errors in component_form.errors.as_data().items():
+                                        for e in errors:
+                                            form.add_error(field, '{} {}: {}'.format(obj, name, ', '.join(e)))
+
+                except IntegrityError:
+                    pass
 
                 if not form.errors:
-                    self.model.objects.bulk_create(new_components)
                     msg = "Added {} {} to {} {}.".format(
                         len(new_components),
                         model_name,

+ 5 - 3
netbox/virtualization/forms.py

@@ -828,6 +828,11 @@ class VirtualMachineBulkAddComponentForm(BootstrapMixin, forms.Form):
         label='Name'
     )
 
+    def clean_tags(self):
+        # Because we're feeding TagField data (on the bulk edit form) to another TagField (on the model form), we
+        # must first convert the list of tags to a string.
+        return ','.join(self.cleaned_data.get('tags'))
+
 
 class InterfaceBulkCreateForm(
     form_from_model(Interface, ['enabled', 'mtu', 'description', 'tags']),
@@ -838,6 +843,3 @@ class InterfaceBulkCreateForm(
         initial=VMInterfaceTypeChoices.TYPE_VIRTUAL,
         widget=forms.HiddenInput()
     )
-    tags = TagField(
-        required=False
-    )