This commit is contained in:
Arthur 2026-09-04 15:06:09 -07:00
parent f6cf81ea5a
commit ea2f1f6189
2 changed files with 16 additions and 2 deletions

View File

@ -723,6 +723,15 @@ def prepare_script_form(script_instance, data, files=None):
"""
data = data.copy() if data is not None else {}
for name, var in script_instance._get_vars().items():
if name not in data and (initial := var.field_attrs.get('initial')) is not None:
if name in data:
continue
if (initial := var.field_attrs.get('initial')) is None:
continue
if isinstance(initial, (list, tuple)) and hasattr(data, 'setlist'):
# Assigning a list to a QueryDict stores it as a single nested value, which a
# multi-select widget reads back as one bogus choice. Set the values individually
# so a MultiChoiceVar/MultiObjectVar default binds as it does for a plain dict.
data.setlist(name, list(initial))
else:
data[name] = initial
return script_instance.as_form(data=data, files=files)

View File

@ -14,7 +14,7 @@ from core.models import Job, ObjectType
from dcim.models import DeviceType, Manufacturer, Site
from extras.choices import *
from extras.models import *
from extras.scripts import BooleanVar, IntegerVar, StringVar
from extras.scripts import BooleanVar, IntegerVar, MultiChoiceVar, StringVar
from extras.scripts import Script as PythonClass
from users.models import Group, ObjectPermission, User
from utilities.testing import TestCase, ViewTestCases
@ -1294,6 +1294,7 @@ class ScriptDefaultBackfillTestCase(TestCase):
label = StringVar(default='hello')
flag = BooleanVar(default=True)
picks = MultiChoiceVar(choices=(('a', 'A'), ('b', 'B'), ('c', 'C')), default=['a', 'b'])
def run(self, data, commit):
return 'Complete'
@ -1328,6 +1329,10 @@ class ScriptDefaultBackfillTestCase(TestCase):
data = mock_enqueue.call_args.kwargs['data']
self.assertEqual(data['label'], 'hello')
self.assertIs(data['flag'], True)
# A multi-value default must be set on the QueryDict with setlist(): a plain
# assignment stores the list as one nested value, which the multi-select widget
# then rejects as a single invalid choice.
self.assertEqual(data['picks'], ['a', 'b'])
class ScriptValidationErrorTestCase(TestCase):