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

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

View File

@ -1668,9 +1668,9 @@ class CableTestCase(
cls.csv_data = (
"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,interface,Interface 2,Device 4,interface,Interface 2",
"Device 3,interface,Interface 3,Device 4,interface,Interface 3",
"Device 3,dcim.interface,Interface 1,Device 4,dcim.interface,Interface 1",
"Device 3,dcim.interface,Interface 2,Device 4,dcim.interface,Interface 2",
"Device 3,dcim.interface,Interface 3,Device 4,dcim.interface,Interface 3",
)
cls.bulk_edit_data = {

View File

@ -6,12 +6,11 @@ from io import StringIO
import django_filters
from django import forms
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.forms import BoundField
from django.urls import reverse
from utilities.api import get_serializer_for_model
from utilities.choices import unpack_grouped_choices
from utilities.validators import EnhancedURLValidator
from . import widgets
@ -21,6 +20,7 @@ from .utils import expand_alphanumeric_pattern, expand_ipaddress_pattern
__all__ = (
'CommentField',
'CSVChoiceField',
'CSVContentTypeField',
'CSVDataField',
'CSVModelChoiceField',
'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):
"""
A field which allows for numeric range expansion