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:
@ -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(
|
||||||
|
@ -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))
|
||||||
|
@ -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 = {
|
||||||
|
Reference in New Issue
Block a user