#5306: Introduce CSVContentTypeField for cable termination types

This commit is contained in:
Jeremy Stretch 2020-12-01 11:03:05 -05:00
parent 23b305847e
commit cadba74b1f
3 changed files with 24 additions and 12 deletions

View File

@ -22,9 +22,10 @@ from tenancy.forms import TenancyFilterForm, TenancyForm
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from utilities.forms import ( from utilities.forms import (
APISelect, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, APISelect, add_blank_choice, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect,
ColorSelect, CommentField, CSVChoiceField, CSVModelChoiceField, CSVModelForm, DynamicModelChoiceField, ColorSelect, CommentField, CSVChoiceField, CSVContentTypeField, CSVModelChoiceField, CSVModelForm,
DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, JSONField, NumericArrayField, SelectWithPK, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, JSONField,
SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, NumericArrayField, SelectWithPK, SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField,
BOOLEAN_WITH_BLANK_CHOICES,
) )
from virtualization.models import Cluster, ClusterGroup from virtualization.models import Cluster, ClusterGroup
from .choices import * from .choices import *
@ -3758,10 +3759,9 @@ class CableCSVForm(CSVModelForm):
to_field_name='name', to_field_name='name',
help_text='Side A device' help_text='Side A device'
) )
side_a_type = CSVModelChoiceField( side_a_type = CSVContentTypeField(
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS, limit_choices_to=CABLE_TERMINATION_MODELS,
to_field_name='model',
help_text='Side A type' help_text='Side A type'
) )
side_a_name = forms.CharField( side_a_name = forms.CharField(
@ -3774,10 +3774,9 @@ class CableCSVForm(CSVModelForm):
to_field_name='name', to_field_name='name',
help_text='Side B device' help_text='Side B device'
) )
side_b_type = CSVModelChoiceField( side_b_type = CSVContentTypeField(
queryset=ContentType.objects.all(), queryset=ContentType.objects.all(),
limit_choices_to=CABLE_TERMINATION_MODELS, limit_choices_to=CABLE_TERMINATION_MODELS,
to_field_name='model',
help_text='Side B type' help_text='Side B type'
) )
side_b_name = forms.CharField( side_b_name = forms.CharField(

View File

@ -1668,9 +1668,9 @@ class CableTestCase(
cls.csv_data = ( cls.csv_data = (
"side_a_device,side_a_type,side_a_name,side_b_device,side_b_type,side_b_name", "side_a_device,side_a_type,side_a_name,side_b_device,side_b_type,side_b_name",
"Device 3,interface,Interface 1,Device 4,interface,Interface 1", "Device 3,dcim.interface,Interface 1,Device 4,dcim.interface,Interface 1",
"Device 3,interface,Interface 2,Device 4,interface,Interface 2", "Device 3,dcim.interface,Interface 2,Device 4,dcim.interface,Interface 2",
"Device 3,interface,Interface 3,Device 4,interface,Interface 3", "Device 3,dcim.interface,Interface 3,Device 4,dcim.interface,Interface 3",
) )
cls.bulk_edit_data = { cls.bulk_edit_data = {

View File

@ -6,12 +6,11 @@ from io import StringIO
import django_filters import django_filters
from django import forms from django import forms
from django.forms.fields import JSONField as _JSONField, InvalidJSONInput from django.forms.fields import JSONField as _JSONField, InvalidJSONInput
from django.core.exceptions import MultipleObjectsReturned from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import Count from django.db.models import Count
from django.forms import BoundField from django.forms import BoundField
from django.urls import reverse from django.urls import reverse
from utilities.api import get_serializer_for_model
from utilities.choices import unpack_grouped_choices from utilities.choices import unpack_grouped_choices
from utilities.validators import EnhancedURLValidator from utilities.validators import EnhancedURLValidator
from . import widgets from . import widgets
@ -21,6 +20,7 @@ from .utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
__all__ = ( __all__ = (
'CommentField', 'CommentField',
'CSVChoiceField', 'CSVChoiceField',
'CSVContentTypeField',
'CSVDataField', 'CSVDataField',
'CSVModelChoiceField', 'CSVModelChoiceField',
'DynamicModelChoiceField', 'DynamicModelChoiceField',
@ -141,6 +141,19 @@ class CSVModelChoiceField(forms.ModelChoiceField):
) )
class CSVContentTypeField(CSVModelChoiceField):
def to_python(self, value):
try:
app_label, model = value.split('.')
except ValueError:
raise forms.ValidationError(f'Object type must be specified as "<app>.<model>"')
try:
return self.queryset.get(app_label=app_label, model=model)
except ObjectDoesNotExist:
raise forms.ValidationError(f'Invalid object type')
class ExpandableNameField(forms.CharField): class ExpandableNameField(forms.CharField):
""" """
A field which allows for numeric range expansion A field which allows for numeric range expansion