mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-09 09:59:37 -06:00
Merge pull request #20725 from netbox-community/20645-bulk-upload
20645 CSVChoiceField use default if blank
This commit is contained in:
commit
6c2a6d0e90
@ -18,6 +18,20 @@ __all__ = (
|
||||
)
|
||||
|
||||
|
||||
class CSVSelectWidget(forms.Select):
|
||||
"""
|
||||
Custom Select widget for CSV imports that treats blank values as omitted.
|
||||
This allows model defaults to be applied when a CSV field is present but empty.
|
||||
"""
|
||||
def value_omitted_from_data(self, data, files, name):
|
||||
# Check if value is omitted using parent behavior
|
||||
if super().value_omitted_from_data(data, files, name):
|
||||
return True
|
||||
# Treat blank/empty strings as omitted to allow model defaults
|
||||
value = data.get(name)
|
||||
return value == '' or value is None
|
||||
|
||||
|
||||
class CSVChoicesMixin:
|
||||
STATIC_CHOICES = True
|
||||
|
||||
@ -29,8 +43,9 @@ class CSVChoicesMixin:
|
||||
class CSVChoiceField(CSVChoicesMixin, forms.ChoiceField):
|
||||
"""
|
||||
A CSV field which accepts a single selection value.
|
||||
Treats blank CSV values as omitted to allow model defaults.
|
||||
"""
|
||||
pass
|
||||
widget = CSVSelectWidget
|
||||
|
||||
|
||||
class CSVMultipleChoiceField(CSVChoicesMixin, forms.MultipleChoiceField):
|
||||
@ -46,7 +61,12 @@ class CSVMultipleChoiceField(CSVChoicesMixin, forms.MultipleChoiceField):
|
||||
|
||||
|
||||
class CSVTypedChoiceField(forms.TypedChoiceField):
|
||||
"""
|
||||
A CSV field for typed choice values.
|
||||
Treats blank CSV values as omitted to allow model defaults.
|
||||
"""
|
||||
STATIC_CHOICES = True
|
||||
widget = CSVSelectWidget
|
||||
|
||||
|
||||
class CSVModelChoiceField(forms.ModelChoiceField):
|
||||
|
||||
@ -4,6 +4,7 @@ from django.test import TestCase
|
||||
from dcim.models import Site
|
||||
from netbox.choices import ImportFormatChoices
|
||||
from utilities.forms.bulk_import import BulkImportForm
|
||||
from utilities.forms.fields.csv import CSVSelectWidget
|
||||
from utilities.forms.forms import BulkRenameForm
|
||||
from utilities.forms.utils import get_field_value, expand_alphanumeric_pattern, expand_ipaddress_pattern
|
||||
|
||||
@ -448,3 +449,35 @@ class GetFieldValueTest(TestCase):
|
||||
get_field_value(form, 'site'),
|
||||
None
|
||||
)
|
||||
|
||||
|
||||
class CSVSelectWidgetTest(TestCase):
|
||||
"""
|
||||
Validate that CSVSelectWidget treats blank values as omitted.
|
||||
This allows model defaults to be applied when CSV fields are present but empty.
|
||||
Related to issue #20645.
|
||||
"""
|
||||
|
||||
def test_blank_value_treated_as_omitted(self):
|
||||
"""Test that blank string values are treated as omitted"""
|
||||
widget = CSVSelectWidget()
|
||||
data = {'test_field': ''}
|
||||
self.assertTrue(widget.value_omitted_from_data(data, {}, 'test_field'))
|
||||
|
||||
def test_none_value_treated_as_omitted(self):
|
||||
"""Test that None values are treated as omitted"""
|
||||
widget = CSVSelectWidget()
|
||||
data = {'test_field': None}
|
||||
self.assertTrue(widget.value_omitted_from_data(data, {}, 'test_field'))
|
||||
|
||||
def test_missing_field_treated_as_omitted(self):
|
||||
"""Test that missing fields are treated as omitted"""
|
||||
widget = CSVSelectWidget()
|
||||
data = {}
|
||||
self.assertTrue(widget.value_omitted_from_data(data, {}, 'test_field'))
|
||||
|
||||
def test_valid_value_not_omitted(self):
|
||||
"""Test that valid values are not treated as omitted"""
|
||||
widget = CSVSelectWidget()
|
||||
data = {'test_field': 'valid_value'}
|
||||
self.assertFalse(widget.value_omitted_from_data(data, {}, 'test_field'))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user