Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

13983 Add nested arrays for extra_choices in CustomFieldChoiceSet #14470

Merged
merged 9 commits into from
Dec 14, 2023
Merged
20 changes: 19 additions & 1 deletion netbox/extras/forms/bulk_import.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import re

from django import forms
from django.contrib.contenttypes.models import ContentType
from django.contrib.postgres.forms import SimpleArrayField
Expand Down Expand Up @@ -76,7 +78,10 @@ class CustomFieldChoiceSetImportForm(CSVModelForm):
extra_choices = SimpleArrayField(
base_field=forms.CharField(),
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:
Expand All @@ -85,6 +90,19 @@ class Meta:
'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))
arthanson marked this conversation as resolved.
Show resolved Hide resolved
return data


class CustomLinkImportForm(CSVModelForm):
content_types = CSVMultipleContentTypeField(
Expand Down
14 changes: 14 additions & 0 deletions netbox/extras/forms/model_forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,25 @@ class Meta:
model = CustomFieldChoiceSet
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):
data = []
for line in self.cleaned_data['extra_choices'].splitlines():
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))
Expand Down
12 changes: 9 additions & 3 deletions netbox/extras/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ def setUpTestData(cls):
name='Choice Set 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)

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

cls.csv_data = (
'name,extra_choices',
'Choice Set 4,"D1,D2,D3"',
'Choice Set 5,"E1,E2,E3"',
'Choice Set 6,"F1,F2,F3"',
'Choice Set 5,"D1,D2,D3"',
'Choice Set 6,"E1,E2,E3"',
'Choice Set 7,"F1,F2,F3"',
'Choice Set 8,"F1:L1,F2:L2,F3:L3"',
)

cls.csv_update_data = (
'id,extra_choices',
f'{choice_sets[0].pk},"A,B,C"',
f'{choice_sets[1].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 = {
Expand Down