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

Closes #5531: Ensure consistent calls to parent clean() methods for models, forms

This commit is contained in:
Jeremy Stretch
2020-12-28 12:54:42 -05:00
parent cc1a43e5d9
commit b2e05aafc1
9 changed files with 28 additions and 1 deletions

View File

@ -134,6 +134,7 @@ class ComponentForm(BootstrapMixin, forms.Form):
)
def clean(self):
super().clean()
# Validate that the number of components being created from both the name_pattern and label_pattern are equal
if self.cleaned_data['label_pattern']:
@ -1438,6 +1439,7 @@ class FrontPortTemplateCreateForm(ComponentTemplateCreateForm):
self.fields['rear_port_set'].choices = choices
def clean(self):
super().clean()
# Validate that the number of ports being created equals the number of selected (rear port, position) tuples
front_port_count = len(self.cleaned_data['name_pattern'])
@ -2929,6 +2931,7 @@ class InterfaceBulkEditForm(
self.fields['lag'].widget.attrs['disabled'] = True
def clean(self):
super().clean()
# Untagged interfaces cannot be assigned tagged VLANs
if self.cleaned_data['mode'] == InterfaceModeChoices.MODE_ACCESS and self.cleaned_data['tagged_vlans']:
@ -3077,6 +3080,7 @@ class FrontPortCreateForm(ComponentCreateForm):
self.fields['rear_port_set'].choices = choices
def clean(self):
super().clean()
# Validate that the number of ports being created equals the number of selected (rear port, position) tuples
front_port_count = len(self.cleaned_data['name_pattern'])
@ -3909,6 +3913,7 @@ class CableBulkEditForm(BootstrapMixin, AddRemoveTagsForm, BulkEditForm):
]
def clean(self):
super().clean()
# Validate length/unit
length = self.cleaned_data.get('length')

View File

@ -193,6 +193,7 @@ class PowerOutletTemplate(ComponentTemplateModel):
unique_together = ('device_type', 'name')
def clean(self):
super().clean()
# Validate power port assignment
if self.power_port and self.power_port.device_type != self.device_type:
@ -278,6 +279,7 @@ class FrontPortTemplate(ComponentTemplateModel):
)
def clean(self):
super().clean()
# Validate rear port assignment
if self.rear_port.device_type != self.device_type:

View File

@ -316,6 +316,7 @@ class PowerPort(CableTermination, PathEndpoint, ComponentModel):
)
def clean(self):
super().clean()
if self.maximum_draw is not None and self.allocated_draw is not None:
if self.allocated_draw > self.maximum_draw:
@ -425,6 +426,7 @@ class PowerOutlet(CableTermination, PathEndpoint, ComponentModel):
)
def clean(self):
super().clean()
# Validate power port assignment
if self.power_port and self.power_port.device != self.device:
@ -555,6 +557,7 @@ class Interface(CableTermination, PathEndpoint, ComponentModel, BaseInterface):
)
def clean(self):
super().clean()
# Virtual interfaces cannot be connected
if self.type in NONCONNECTABLE_IFACE_TYPES and (
@ -668,6 +671,7 @@ class FrontPort(CableTermination, ComponentModel):
)
def clean(self):
super().clean()
# Validate rear port assignment
if self.rear_port.device != self.device:
@ -711,6 +715,7 @@ class RearPort(CableTermination, ComponentModel):
return reverse('dcim:rearport', kwargs={'pk': self.pk})
def clean(self):
super().clean()
# Check that positions count is greater than or equal to the number of associated FrontPorts
frontport_count = self.frontports.count()
@ -768,6 +773,7 @@ class DeviceBay(ComponentModel):
)
def clean(self):
super().clean()
# Validate that the parent Device can have DeviceBays
if not self.device.device_type.is_parent_device:

View File

@ -109,6 +109,7 @@ class RackGroup(MPTTModel, ChangeLoggedModel):
)
def clean(self):
super().clean()
# Parent RackGroup (if any) must belong to the same Site
if self.parent and self.parent.site != self.site:

View File

@ -47,6 +47,8 @@ class CustomFieldModel(models.Model):
])
def clean(self):
super().clean()
custom_fields = {cf.name: cf for cf in CustomField.objects.get_for_model(self)}
# Validate all field values
@ -172,6 +174,8 @@ class CustomField(models.Model):
obj.save()
def clean(self):
super().clean()
# Validate the field's default value (if any)
if self.default is not None:
try:

View File

@ -117,11 +117,15 @@ class Webhook(models.Model):
return self.name
def clean(self):
super().clean()
# At least one action type must be selected
if not self.type_create and not self.type_delete and not self.type_update:
raise ValidationError(
"You must select at least one type: create, update, and/or delete."
)
# CA file path requires SSL verification enabled
if not self.ssl_verification and self.ca_file_path:
raise ValidationError({
'ca_file_path': 'Do not specify a CA certificate file if SSL verification is disabled.'
@ -436,6 +440,7 @@ class ConfigContext(ChangeLoggedModel):
return reverse('extras:configcontext', kwargs={'pk': self.pk})
def clean(self):
super().clean()
# Verify that JSON data is provided as an object
if type(self.data) is not dict:
@ -482,7 +487,6 @@ class ConfigContextModel(models.Model):
return data
def clean(self):
super().clean()
# Verify that JSON data is provided as an object

View File

@ -169,6 +169,8 @@ class ObjectPermissionForm(forms.ModelForm):
self.instance.actions.remove(action)
def clean(self):
super().clean()
object_types = self.cleaned_data.get('object_types')
constraints = self.cleaned_data.get('constraints')

View File

@ -82,6 +82,7 @@ class BulkRenameForm(forms.Form):
)
def clean(self):
super().clean()
# Validate regular expression in "find" field
if self.cleaned_data['use_regex']:
@ -124,6 +125,7 @@ class ImportForm(BootstrapMixin, forms.Form):
)
def clean(self):
super().clean()
data = self.cleaned_data['data']
format = self.cleaned_data['format']

View File

@ -444,6 +444,7 @@ class VMInterface(BaseInterface):
)
def clean(self):
super().clean()
# Validate untagged VLAN
if self.untagged_vlan and self.untagged_vlan.site not in [self.virtual_machine.site, None]: