Refactorization into LabeledComponentForm

This commit is contained in:
Jonathan Senecal 2020-06-08 23:07:12 -04:00
parent 90bc1cd951
commit 4301c06d17
2 changed files with 44 additions and 225 deletions

View File

@ -22,10 +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, APISelectMultiple, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, APISelect, APISelectMultiple, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm,
BulkEditNullBooleanSelect, ColorSelect, CommentField, ConfirmationForm, CSVChoiceField, CSVModelChoiceField, BOOLEAN_WITH_BLANK_CHOICES, BulkEditNullBooleanSelect, ColorSelect, CommentField, ConfirmationForm, CSVChoiceField,
CSVModelForm, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, CSVModelChoiceField, CSVModelForm, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField,
JSONField, SelectWithPK, SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, form_from_model, JSONField, LabeledComponentForm, SelectWithPK, SmallTextarea, SlugField, StaticSelect2,
BOOLEAN_WITH_BLANK_CHOICES, StaticSelect2Multiple, TagFilterField,
) )
from virtualization.models import Cluster, ClusterGroup, VirtualMachine from virtualization.models import Cluster, ClusterGroup, VirtualMachine
from .choices import * from .choices import *
@ -1039,34 +1039,15 @@ class ConsolePortTemplateForm(BootstrapMixin, forms.ModelForm):
} }
class ConsolePortTemplateCreateForm(BootstrapMixin, forms.Form): class ConsolePortTemplateCreateForm(LabeledComponentForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
queryset=DeviceType.objects.all() queryset=DeviceType.objects.all()
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(ConsolePortTypeChoices), choices=add_blank_choice(ConsolePortTypeChoices),
widget=StaticSelect2() widget=StaticSelect2()
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class ConsolePortTemplateBulkEditForm(BootstrapMixin, BulkEditForm): class ConsolePortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
@ -1095,34 +1076,15 @@ class ConsoleServerPortTemplateForm(BootstrapMixin, forms.ModelForm):
} }
class ConsoleServerPortTemplateCreateForm(BootstrapMixin, forms.Form): class ConsoleServerPortTemplateCreateForm(LabeledComponentForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
queryset=DeviceType.objects.all() queryset=DeviceType.objects.all()
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(ConsolePortTypeChoices), choices=add_blank_choice(ConsolePortTypeChoices),
widget=StaticSelect2() widget=StaticSelect2()
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class ConsoleServerPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm): class ConsoleServerPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
@ -1151,17 +1113,10 @@ class PowerPortTemplateForm(BootstrapMixin, forms.ModelForm):
} }
class PowerPortTemplateCreateForm(BootstrapMixin, forms.Form): class PowerPortTemplateCreateForm(LabeledComponentForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
queryset=DeviceType.objects.all() queryset=DeviceType.objects.all()
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(PowerPortTypeChoices), choices=add_blank_choice(PowerPortTypeChoices),
required=False required=False
@ -1177,18 +1132,6 @@ class PowerPortTemplateCreateForm(BootstrapMixin, forms.Form):
help_text="Allocated power draw (watts)" help_text="Allocated power draw (watts)"
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class PowerPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm): class PowerPortTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
@ -1237,17 +1180,10 @@ class PowerOutletTemplateForm(BootstrapMixin, forms.ModelForm):
) )
class PowerOutletTemplateCreateForm(BootstrapMixin, forms.Form): class PowerOutletTemplateCreateForm(LabeledComponentForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
queryset=DeviceType.objects.all() queryset=DeviceType.objects.all()
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(PowerOutletTypeChoices), choices=add_blank_choice(PowerOutletTypeChoices),
required=False required=False
@ -1273,18 +1209,6 @@ class PowerOutletTemplateCreateForm(BootstrapMixin, forms.Form):
device_type=device_type device_type=device_type
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class PowerOutletTemplateBulkEditForm(BootstrapMixin, BulkEditForm): class PowerOutletTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
@ -1319,17 +1243,10 @@ class InterfaceTemplateForm(BootstrapMixin, forms.ModelForm):
} }
class InterfaceTemplateCreateForm(BootstrapMixin, forms.Form): class InterfaceTemplateCreateForm(LabeledComponentForm):
device_type = DynamicModelChoiceField( device_type = DynamicModelChoiceField(
queryset=DeviceType.objects.all() queryset=DeviceType.objects.all()
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=InterfaceTypeChoices, choices=InterfaceTypeChoices,
widget=StaticSelect2() widget=StaticSelect2()
@ -1339,18 +1256,6 @@ class InterfaceTemplateCreateForm(BootstrapMixin, forms.Form):
label='Management only' label='Management only'
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} interfaces, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm): class InterfaceTemplateBulkEditForm(BootstrapMixin, BulkEditForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
@ -2271,36 +2176,17 @@ class DeviceFilterForm(BootstrapMixin, LocalConfigContextFilterForm, TenancyFilt
# Bulk device component creation # Bulk device component creation
# #
class DeviceBulkAddComponentForm(BootstrapMixin, forms.Form): class DeviceBulkAddComponentForm(LabeledComponentForm):
pk = forms.ModelMultipleChoiceField( pk = forms.ModelMultipleChoiceField(
queryset=Device.objects.all(), queryset=Device.objects.all(),
widget=forms.MultipleHiddenInput() widget=forms.MultipleHiddenInput()
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
def clean_tags(self): def clean_tags(self):
# Because we're feeding TagField data (on the bulk edit form) to another TagField (on the model form), we # Because we're feeding TagField data (on the bulk edit form) to another TagField (on the model form), we
# must first convert the list of tags to a string. # must first convert the list of tags to a string.
return ','.join(self.cleaned_data.get('tags')) return ','.join(self.cleaned_data.get('tags'))
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
# #
# Console ports # Console ports
@ -2332,17 +2218,10 @@ class ConsolePortForm(BootstrapMixin, forms.ModelForm):
} }
class ConsolePortCreateForm(BootstrapMixin, forms.Form): class ConsolePortCreateForm(LabeledComponentForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
queryset=Device.objects.prefetch_related('device_type__manufacturer') queryset=Device.objects.prefetch_related('device_type__manufacturer')
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(ConsolePortTypeChoices), choices=add_blank_choice(ConsolePortTypeChoices),
required=False, required=False,
@ -2356,18 +2235,6 @@ class ConsolePortCreateForm(BootstrapMixin, forms.Form):
required=False required=False
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class ConsolePortBulkCreateForm( class ConsolePortBulkCreateForm(
form_from_model(ConsolePort, ['type', 'description', 'tags']), form_from_model(ConsolePort, ['type', 'description', 'tags']),
@ -2434,17 +2301,10 @@ class ConsoleServerPortForm(BootstrapMixin, forms.ModelForm):
} }
class ConsoleServerPortCreateForm(BootstrapMixin, forms.Form): class ConsoleServerPortCreateForm(LabeledComponentForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
queryset=Device.objects.prefetch_related('device_type__manufacturer') queryset=Device.objects.prefetch_related('device_type__manufacturer')
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(ConsolePortTypeChoices), choices=add_blank_choice(ConsolePortTypeChoices),
required=False, required=False,
@ -2458,18 +2318,6 @@ class ConsoleServerPortCreateForm(BootstrapMixin, forms.Form):
required=False required=False
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class ConsoleServerPortBulkCreateForm( class ConsoleServerPortBulkCreateForm(
form_from_model(ConsoleServerPort, ['type', 'description', 'tags']), form_from_model(ConsoleServerPort, ['type', 'description', 'tags']),
@ -2550,17 +2398,10 @@ class PowerPortForm(BootstrapMixin, forms.ModelForm):
} }
class PowerPortCreateForm(BootstrapMixin, forms.Form): class PowerPortCreateForm(LabeledComponentForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
queryset=Device.objects.prefetch_related('device_type__manufacturer') queryset=Device.objects.prefetch_related('device_type__manufacturer')
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(PowerPortTypeChoices), choices=add_blank_choice(PowerPortTypeChoices),
required=False, required=False,
@ -2583,17 +2424,6 @@ class PowerPortCreateForm(BootstrapMixin, forms.Form):
tags = TagField( tags = TagField(
required=False required=False
) )
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class PowerPortBulkCreateForm( class PowerPortBulkCreateForm(
@ -2674,17 +2504,10 @@ class PowerOutletForm(BootstrapMixin, forms.ModelForm):
) )
class PowerOutletCreateForm(BootstrapMixin, forms.Form): class PowerOutletCreateForm(LabeledComponentForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
queryset=Device.objects.prefetch_related('device_type__manufacturer') queryset=Device.objects.prefetch_related('device_type__manufacturer')
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=add_blank_choice(PowerOutletTypeChoices), choices=add_blank_choice(PowerOutletTypeChoices),
required=False, required=False,
@ -2715,18 +2538,6 @@ class PowerOutletCreateForm(BootstrapMixin, forms.Form):
) )
self.fields['power_port'].queryset = PowerPort.objects.filter(device=device) self.fields['power_port'].queryset = PowerPort.objects.filter(device=device)
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} ports, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class PowerOutletBulkCreateForm( class PowerOutletBulkCreateForm(
form_from_model(PowerOutlet, ['type', 'feed_leg', 'description', 'tags']), form_from_model(PowerOutlet, ['type', 'feed_leg', 'description', 'tags']),
@ -2915,17 +2726,11 @@ class InterfaceForm(InterfaceCommonForm, BootstrapMixin, forms.ModelForm):
self.fields['tagged_vlans'].widget.add_additional_query_param('site_id', device.site.pk) self.fields['tagged_vlans'].widget.add_additional_query_param('site_id', device.site.pk)
class InterfaceCreateForm(BootstrapMixin, InterfaceCommonForm, forms.Form): class InterfaceCreateForm(InterfaceCommonForm, LabeledComponentForm):
component_type = 'interface'
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
queryset=Device.objects.prefetch_related('device_type__manufacturer') queryset=Device.objects.prefetch_related('device_type__manufacturer')
) )
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
type = forms.ChoiceField( type = forms.ChoiceField(
choices=InterfaceTypeChoices, choices=InterfaceTypeChoices,
widget=StaticSelect2(), widget=StaticSelect2(),
@ -3006,25 +2811,12 @@ class InterfaceCreateForm(BootstrapMixin, InterfaceCommonForm, forms.Form):
self.fields['untagged_vlan'].widget.add_additional_query_param('site_id', device.site.pk) self.fields['untagged_vlan'].widget.add_additional_query_param('site_id', device.site.pk)
self.fields['tagged_vlans'].widget.add_additional_query_param('site_id', device.site.pk) self.fields['tagged_vlans'].widget.add_additional_query_param('site_id', device.site.pk)
def clean(self):
# Validate that the number of ports being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} interfaces, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, label_pattern_count)
})
class InterfaceBulkCreateForm( class InterfaceBulkCreateForm(
form_from_model(Interface, ['type', 'enabled', 'mtu', 'mgmt_only', 'description', 'tags']), form_from_model(Interface, ['type', 'enabled', 'mtu', 'mgmt_only', 'description', 'tags']),
DeviceBulkAddComponentForm DeviceBulkAddComponentForm
): ):
pass component_type = 'interface'
class InterfaceBulkEditForm( class InterfaceBulkEditForm(

View File

@ -804,6 +804,33 @@ class ImportForm(BootstrapMixin, forms.Form):
}) })
class LabeledComponentForm(BootstrapMixin, forms.Form):
"""
Base form for adding label pattern validation to `Create` forms
"""
component_type = 'port'
name_pattern = ExpandableNameField(
label='Name'
)
label_pattern = ExpandableNameField(
label='Label',
required=False
)
def clean(self):
# Validate that the number of components being created from both the name_pattern and label_pattern are equal
name_pattern_count = len(self.cleaned_data['name_pattern'])
label_pattern_count = len(self.cleaned_data['label_pattern'])
if label_pattern_count and name_pattern_count != label_pattern_count:
raise forms.ValidationError({
'label_pattern': 'The provided name pattern will create {} {}s, however {} labels will '
'be generated. These counts must match.'.format(
name_pattern_count, self.component_type, label_pattern_count)
}, code='label_pattern_mismatch')
class TableConfigForm(BootstrapMixin, forms.Form): class TableConfigForm(BootstrapMixin, forms.Form):
""" """
Form for configuring user's table preferences. Form for configuring user's table preferences.