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

Closes #4885: Add MultiChoiceVar for custom scripts

Jeremy Stretch 5 лет назад
Родитель
Сommit
3c395e7c9f

+ 4 - 0
docs/additional-features/custom-scripts.md

@@ -154,6 +154,10 @@ CHOICES = (
 direction = ChoiceVar(choices=CHOICES)
 ```
 
+### MultiChoiceVar
+
+Similar to `ChoiceVar`, but allows for the selection of multiple choices.
+
 ### ObjectVar
 
 A NetBox object of a particular type, identified by the associated queryset. Most models will utilize the REST API to retrieve available options: Note that any filtering on the queryset in this case has no effect.

+ 8 - 0
docs/release-notes/version-2.8.md

@@ -1,5 +1,13 @@
 # NetBox v2.8
 
+## v2.8.10 (FUTURE)
+
+### Enhancements
+
+* [#4885](https://github.com/netbox-community/netbox/issues/4885) - Add MultiChoiceVar for custom scripts
+
+---
+
 ## v2.8.9 (2020-08-04)
 
 ### Enhancements

+ 8 - 0
netbox/extras/scripts.py

@@ -32,6 +32,7 @@ __all__ = [
     'IPAddressVar',
     'IPAddressWithMaskVar',
     'IPNetworkVar',
+    'MultiChoiceVar',
     'MultiObjectVar',
     'ObjectVar',
     'Script',
@@ -165,6 +166,13 @@ class ChoiceVar(ScriptVariable):
         self.field_attrs['choices'] = choices
 
 
+class MultiChoiceVar(ChoiceVar):
+    """
+    Like ChoiceVar, but allows for the selection of multiple choices.
+    """
+    form_field = forms.MultipleChoiceField
+
+
 class ObjectVar(ScriptVariable):
     """
     A single object within NetBox.

+ 34 - 9
netbox/extras/tests/test_scripts.py

@@ -5,6 +5,12 @@ from netaddr import IPAddress, IPNetwork
 from dcim.models import DeviceRole
 from extras.scripts import *
 
+CHOICES = (
+    ('ff0000', 'Red'),
+    ('00ff00', 'Green'),
+    ('0000ff', 'Blue')
+)
+
 
 class ScriptVariablesTest(TestCase):
 
@@ -101,12 +107,6 @@ class ScriptVariablesTest(TestCase):
 
     def test_choicevar(self):
 
-        CHOICES = (
-            ('ff0000', 'Red'),
-            ('00ff00', 'Green'),
-            ('0000ff', 'Blue')
-        )
-
         class TestScript(Script):
 
             var1 = ChoiceVar(
@@ -114,12 +114,37 @@ class ScriptVariablesTest(TestCase):
             )
 
         # Validate valid choice
-        data = {'var1': CHOICES[0][0]}
+        data = {'var1': 'ff0000'}
+        form = TestScript().as_form(data)
+        self.assertTrue(form.is_valid())
+        self.assertEqual(form.cleaned_data['var1'], 'ff0000')
+
+        # Validate invalid choice
+        data = {'var1': 'taupe'}
+        form = TestScript().as_form(data)
+        self.assertFalse(form.is_valid())
+
+    def test_multichoicevar(self):
+
+        class TestScript(Script):
+
+            var1 = MultiChoiceVar(
+                choices=CHOICES
+            )
+
+        # Validate single choice
+        data = {'var1': ['ff0000']}
+        form = TestScript().as_form(data)
+        self.assertTrue(form.is_valid())
+        self.assertEqual(form.cleaned_data['var1'], ['ff0000'])
+
+        # Validate multiple choices
+        data = {'var1': ('ff0000', '00ff00')}
         form = TestScript().as_form(data)
         self.assertTrue(form.is_valid())
-        self.assertEqual(form.cleaned_data['var1'], CHOICES[0][0])
+        self.assertEqual(form.cleaned_data['var1'], ['ff0000', '00ff00'])
 
-        # Validate invalid choices
+        # Validate invalid choice
         data = {'var1': 'taupe'}
         form = TestScript().as_form(data)
         self.assertFalse(form.is_valid())