1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

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
This commit is contained in:
Arthur Hanson
2023-12-14 12:18:56 -08:00
committed by GitHub
parent b93735861d
commit 69bf1472d2
3 changed files with 42 additions and 4 deletions

View File

@ -1,3 +1,5 @@
import re
from django import forms from django import forms
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms import SimpleArrayField from django.contrib.postgres.forms import SimpleArrayField
@ -76,7 +78,10 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
extra_choices = SimpleArrayField( extra_choices = SimpleArrayField(
base_field=forms.CharField(), base_field=forms.CharField(),
required=False, required=False,
help_text=_('Comma-separated list of field choices') help_text=_(
'Quoted string of comma-separated field choices with optional labels separated by colon: '
'"choice1:First Choice,choice2:Second Choice"'
)
) )
class Meta: class Meta:
@ -85,6 +90,19 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
'name', 'description', 'extra_choices', 'order_alphabetically', 'name', 'description', 'extra_choices', 'order_alphabetically',
) )
def clean_extra_choices(self):
if isinstance(self.cleaned_data['extra_choices'], list):
data = []
for line in self.cleaned_data['extra_choices']:
try:
value, label = re.split(r'(?<!\\):', line, maxsplit=1)
value = value.replace('\\:', ':')
label = label.replace('\\:', ':')
except ValueError:
value, label = line, line
data.append((value, label))
return data
class CustomLinkImportForm(CSVModelForm): class CustomLinkImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField( content_types = CSVMultipleContentTypeField(

View File

@ -104,11 +104,25 @@ class CustomFieldChoiceSetForm(BootstrapMixin, forms.ModelForm):
model = CustomFieldChoiceSet model = CustomFieldChoiceSet
fields = ('name', 'description', 'base_choices', 'extra_choices', 'order_alphabetically') fields = ('name', 'description', 'base_choices', 'extra_choices', 'order_alphabetically')
def __init__(self, *args, initial=None, **kwargs):
super().__init__(*args, initial=initial, **kwargs)
# Escape colons in extra_choices
if 'extra_choices' in self.initial and self.initial['extra_choices']:
choices = []
for choice in self.initial['extra_choices']:
choice = (choice[0].replace(':', '\\:'), choice[1].replace(':', '\\:'))
choices.append(choice)
self.initial['extra_choices'] = choices
def clean_extra_choices(self): def clean_extra_choices(self):
data = [] data = []
for line in self.cleaned_data['extra_choices'].splitlines(): for line in self.cleaned_data['extra_choices'].splitlines():
try: try:
value, label = re.split(r'(?<!\\):', line, maxsplit=1) value, label = re.split(r'(?<!\\):', line, maxsplit=1)
value = value.replace('\\:', ':')
label = label.replace('\\:', ':')
except ValueError: except ValueError:
value, label = line, line value, label = line, line
data.append((value, label)) data.append((value, label))

View File

@ -93,6 +93,10 @@ class CustomFieldChoiceSetTestCase(ViewTestCases.PrimaryObjectViewTestCase):
name='Choice Set 3', name='Choice Set 3',
extra_choices=(('C1', 'Choice 1'), ('C2', 'Choice 2'), ('C3', 'Choice 3')) extra_choices=(('C1', 'Choice 1'), ('C2', 'Choice 2'), ('C3', 'Choice 3'))
), ),
CustomFieldChoiceSet(
name='Choice Set 4',
extra_choices=(('D1', 'Choice 1'), ('D2', 'Choice 2'), ('D3', 'Choice 3'))
),
) )
CustomFieldChoiceSet.objects.bulk_create(choice_sets) CustomFieldChoiceSet.objects.bulk_create(choice_sets)
@ -103,9 +107,10 @@ class CustomFieldChoiceSetTestCase(ViewTestCases.PrimaryObjectViewTestCase):
cls.csv_data = ( cls.csv_data = (
'name,extra_choices', 'name,extra_choices',
'Choice Set 4,"D1,D2,D3"', 'Choice Set 5,"D1,D2,D3"',
'Choice Set 5,"E1,E2,E3"', 'Choice Set 6,"E1,E2,E3"',
'Choice Set 6,"F1,F2,F3"', 'Choice Set 7,"F1,F2,F3"',
'Choice Set 8,"F1:L1,F2:L2,F3:L3"',
) )
cls.csv_update_data = ( cls.csv_update_data = (
@ -113,6 +118,7 @@ class CustomFieldChoiceSetTestCase(ViewTestCases.PrimaryObjectViewTestCase):
f'{choice_sets[0].pk},"A,B,C"', f'{choice_sets[0].pk},"A,B,C"',
f'{choice_sets[1].pk},"A,B,C"', f'{choice_sets[1].pk},"A,B,C"',
f'{choice_sets[2].pk},"A,B,C"', f'{choice_sets[2].pk},"A,B,C"',
f'{choice_sets[3].pk},"A:L1,B:L2,C:L3"',
) )
cls.bulk_edit_data = { cls.bulk_edit_data = {