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

Fixes #15812: Add Date(Time)Var for scripts to allow much easier date… (#15821)

* Fixes #15812: Add Date(Time)Var for scripts to allow much easier date input

* Extend tests for invalid data

---------

Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
JCWasmx86 1 год назад
Родитель
Сommit
3cbade536e

+ 8 - 0
docs/customization/custom-scripts.md

@@ -285,6 +285,14 @@ An IPv4 or IPv6 network with a mask. Returns a `netaddr.IPNetwork` object. Two a
 * `min_prefix_length` - Minimum length of the mask
 * `max_prefix_length` - Maximum length of the mask
 
+### DateVar
+
+A calendar date. Returns a `datetime.date` object.
+
+### DateTimeVar
+
+A complete date & time. Returns a `datetime.datetime` object.
+
 ## Running Custom Scripts
 
 !!! note

+ 25 - 0
netbox/extras/scripts.py

@@ -24,6 +24,7 @@ from ipam.validators import MaxPrefixLengthValidator, MinPrefixLengthValidator,
 from utilities.exceptions import AbortScript, AbortTransaction
 from utilities.forms import add_blank_choice
 from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
+from utilities.forms.widgets import DatePicker, DateTimePicker
 from .context_managers import event_tracking
 from .forms import ScriptForm
 
@@ -31,6 +32,8 @@ __all__ = (
     'BaseScript',
     'BooleanVar',
     'ChoiceVar',
+    'DateVar',
+    'DateTimeVar',
     'FileVar',
     'IntegerVar',
     'IPAddressVar',
@@ -172,6 +175,28 @@ class ChoiceVar(ScriptVariable):
         self.field_attrs['choices'] = add_blank_choice(choices)
 
 
+class DateVar(ScriptVariable):
+    """
+    A date.
+    """
+    form_field = forms.DateField
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.form_field.widget = DatePicker()
+
+
+class DateTimeVar(ScriptVariable):
+    """
+    A date and a time.
+    """
+    form_field = forms.DateTimeField
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.form_field.widget = DateTimePicker()
+
+
 class MultiChoiceVar(ScriptVariable):
     """
     Like ChoiceVar, but allows for the selection of multiple choices.

+ 45 - 0
netbox/extras/tests/test_scripts.py

@@ -1,4 +1,5 @@
 import tempfile
+from datetime import date, datetime, timezone
 
 from django.core.files.uploadedfile import SimpleUploadedFile
 from django.test import TestCase
@@ -322,3 +323,47 @@ class ScriptVariablesTest(TestCase):
         form = TestScript().as_form(data, None)
         self.assertTrue(form.is_valid())
         self.assertEqual(form.cleaned_data['var1'], IPNetwork(data['var1']))
+
+    def test_datevar(self):
+
+        class TestScript(Script):
+
+            var1 = DateVar()
+            var2 = DateVar(required=False)
+
+        # Test date validation
+        data = {'var1': 'not a date'}
+        form = TestScript().as_form(data, None)
+        self.assertFalse(form.is_valid())
+        self.assertIn('var1', form.errors)
+
+        # Validate valid data
+        input_date = date(2024, 4, 1)
+        data = {'var1': input_date}
+        form = TestScript().as_form(data, None)
+        self.assertTrue(form.is_valid())
+        self.assertEqual(form.cleaned_data['var1'], input_date)
+        # Validate required=False works for this Var type
+        self.assertEqual(form.cleaned_data['var2'], None)
+
+    def test_datetimevar(self):
+
+        class TestScript(Script):
+
+            var1 = DateTimeVar()
+            var2 = DateTimeVar(required=False)
+
+        # Test datetime validation
+        data = {'var1': 'not a datetime'}
+        form = TestScript().as_form(data, None)
+        self.assertFalse(form.is_valid())
+        self.assertIn('var1', form.errors)
+
+        # Validate valid data
+        input_datetime = datetime(2024, 4, 1, 8, 0, 0, 0, timezone.utc)
+        data = {'var1': input_datetime}
+        form = TestScript().as_form(data, None)
+        self.assertTrue(form.is_valid())
+        self.assertEqual(form.cleaned_data['var1'], input_datetime)
+        # Validate required=False works for this Var type
+        self.assertEqual(form.cleaned_data['var2'], None)