Skip to content

Commit 69bf147

Browse files
authored
13983 Add nested arrays for extra_choices in CustomFieldChoiceSet (#14470)
* 13983 split array fields in CSV data for CustomFieldChoices * 13983 fix help text * 13983 update tests * 13983 use re for split * 13983 replace escaped chars * 13983 fix escape handling * 13983 fix escape handling * 13983 fix escape handling
1 parent b937358 commit 69bf147

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

netbox/extras/forms/bulk_import.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import re
2+
13
from django import forms
24
from django.contrib.contenttypes.models import ContentType
35
from django.contrib.postgres.forms import SimpleArrayField
@@ -76,7 +78,10 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
7678
extra_choices = SimpleArrayField(
7779
base_field=forms.CharField(),
7880
required=False,
79-
help_text=_('Comma-separated list of field choices')
81+
help_text=_(
82+
'Quoted string of comma-separated field choices with optional labels separated by colon: '
83+
'"choice1:First Choice,choice2:Second Choice"'
84+
)
8085
)
8186

8287
class Meta:
@@ -85,6 +90,19 @@ class Meta:
8590
'name', 'description', 'extra_choices', 'order_alphabetically',
8691
)
8792

93+
def clean_extra_choices(self):
94+
if isinstance(self.cleaned_data['extra_choices'], list):
95+
data = []
96+
for line in self.cleaned_data['extra_choices']:
97+
try:
98+
value, label = re.split(r'(?<!\\):', line, maxsplit=1)
99+
value = value.replace('\\:', ':')
100+
label = label.replace('\\:', ':')
101+
except ValueError:
102+
value, label = line, line
103+
data.append((value, label))
104+
return data
105+
88106

89107
class CustomLinkImportForm(CSVModelForm):
90108
content_types = CSVMultipleContentTypeField(

netbox/extras/forms/model_forms.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,25 @@ class Meta:
104104
model = CustomFieldChoiceSet
105105
fields = ('name', 'description', 'base_choices', 'extra_choices', 'order_alphabetically')
106106

107+
def __init__(self, *args, initial=None, **kwargs):
108+
super().__init__(*args, initial=initial, **kwargs)
109+
110+
# Escape colons in extra_choices
111+
if 'extra_choices' in self.initial and self.initial['extra_choices']:
112+
choices = []
113+
for choice in self.initial['extra_choices']:
114+
choice = (choice[0].replace(':', '\\:'), choice[1].replace(':', '\\:'))
115+
choices.append(choice)
116+
117+
self.initial['extra_choices'] = choices
118+
107119
def clean_extra_choices(self):
108120
data = []
109121
for line in self.cleaned_data['extra_choices'].splitlines():
110122
try:
111123
value, label = re.split(r'(?<!\\):', line, maxsplit=1)
124+
value = value.replace('\\:', ':')
125+
label = label.replace('\\:', ':')
112126
except ValueError:
113127
value, label = line, line
114128
data.append((value, label))

netbox/extras/tests/test_views.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ def setUpTestData(cls):
9393
name='Choice Set 3',
9494
extra_choices=(('C1', 'Choice 1'), ('C2', 'Choice 2'), ('C3', 'Choice 3'))
9595
),
96+
CustomFieldChoiceSet(
97+
name='Choice Set 4',
98+
extra_choices=(('D1', 'Choice 1'), ('D2', 'Choice 2'), ('D3', 'Choice 3'))
99+
),
96100
)
97101
CustomFieldChoiceSet.objects.bulk_create(choice_sets)
98102

@@ -103,16 +107,18 @@ def setUpTestData(cls):
103107

104108
cls.csv_data = (
105109
'name,extra_choices',
106-
'Choice Set 4,"D1,D2,D3"',
107-
'Choice Set 5,"E1,E2,E3"',
108-
'Choice Set 6,"F1,F2,F3"',
110+
'Choice Set 5,"D1,D2,D3"',
111+
'Choice Set 6,"E1,E2,E3"',
112+
'Choice Set 7,"F1,F2,F3"',
113+
'Choice Set 8,"F1:L1,F2:L2,F3:L3"',
109114
)
110115

111116
cls.csv_update_data = (
112117
'id,extra_choices',
113118
f'{choice_sets[0].pk},"A,B,C"',
114119
f'{choice_sets[1].pk},"A,B,C"',
115120
f'{choice_sets[2].pk},"A,B,C"',
121+
f'{choice_sets[3].pk},"A:L1,B:L2,C:L3"',
116122
)
117123

118124
cls.bulk_edit_data = {

0 commit comments

Comments
 (0)