Changes needed to implement Custom Field imports via CSV, and enable this when importing devices

This commit is contained in:
Anthony Eden 2019-03-01 20:59:46 +11:00
parent 6f5c35c278
commit 9cb6b792ba
4 changed files with 26 additions and 3 deletions

View File

@ -1419,7 +1419,7 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
self.initial['rack'] = self.instance.parent_bay.device.rack_id
class BaseDeviceCSVForm(forms.ModelForm):
class BaseDeviceCSVForm(CustomFieldForm):
device_role = forms.ModelChoiceField(
queryset=DeviceRole.objects.all(),
to_field_name='name',

View File

@ -12,7 +12,7 @@ from dcim.models import DeviceRole, Platform, Region, Site
from tenancy.models import Tenant, TenantGroup
from utilities.forms import (
add_blank_choice, APISelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ContentTypeSelect,
FilterChoiceField, FilterTreeNodeMultipleChoiceField, LaxURLField, JSONField, SlugField,
CSVChoiceFieldCustom, FilterChoiceField, FilterTreeNodeMultipleChoiceField, LaxURLField, JSONField, SlugField,
)
from .constants import (
CF_FILTER_DISABLED, CF_TYPE_BOOLEAN, CF_TYPE_DATE, CF_TYPE_INTEGER, CF_TYPE_SELECT, CF_TYPE_URL,
@ -75,7 +75,7 @@ def get_custom_fields_for_model(content_type, filterable_only=False, bulk_edit=F
default_choice = cf.choices.get(value=initial).pk
except ObjectDoesNotExist:
pass
field = forms.TypedChoiceField(choices=choices, coerce=int, required=cf.required, initial=default_choice)
field = CSVChoiceFieldCustom(choices=choices, coerce=int, required=cf.required, initial=default_choice)
# URL
elif cf.type == CF_TYPE_URL:

View File

@ -436,6 +436,26 @@ class CSVChoiceField(forms.ChoiceField):
return self.choice_values[value]
class CSVChoiceFieldCustom(forms.TypedChoiceField):
"""
For custom fields, invert the provided set of choices to take the human-friendly label as input, and return the database value.
"""
def __init__(self, choices=(), coerce=lambda val: val, empty_value='', *args, **kwargs):
super().__init__(choices=choices, coerce=coerce, empty_value=empty_value, *args, **kwargs)
self.choice_values = {label: value for value, label in unpack_grouped_choices(choices)}
def clean(self, value):
if not value:
return None
for choice in self.choice_values:
if str(choice) == value:
return self.choice_values[choice]
return super().clean(value)
class ExpandableNameField(forms.CharField):
"""
A field which allows for numeric range expansion

View File

@ -143,6 +143,9 @@ def example_choices(field, arg=3):
break
if not value or not label:
continue
if hasattr(label, 'value'):
# Handling for custom field choice labels
label = label.value
examples.append(label)
return ', '.join(examples) or 'None'