mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Closes #12133: Move any instance mutations inside clean() to save()
This commit is contained in:
@ -152,8 +152,6 @@ class Cable(PrimaryModel):
|
||||
# Validate length and length_unit
|
||||
if self.length is not None and not self.length_unit:
|
||||
raise ValidationError("Must specify a unit when setting a cable length")
|
||||
elif self.length is None:
|
||||
self.length_unit = ''
|
||||
|
||||
if self.pk is None and (not self.a_terminations or not self.b_terminations):
|
||||
raise ValidationError("Must define A and B terminations when creating a new cable.")
|
||||
@ -187,6 +185,10 @@ class Cable(PrimaryModel):
|
||||
else:
|
||||
self._abs_length = None
|
||||
|
||||
# Clear length_unit if no length is defined
|
||||
if self.length is None:
|
||||
self.length_unit = ''
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
# Update the private pk used in __str__ in case this is a new object (i.e. just got its pk)
|
||||
|
@ -794,8 +794,6 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
|
||||
raise ValidationError({
|
||||
'rf_channel_frequency': "Cannot specify custom frequency with channel selected.",
|
||||
})
|
||||
elif self.rf_channel:
|
||||
self.rf_channel_frequency = get_channel_attr(self.rf_channel, 'frequency')
|
||||
|
||||
# Validate channel width against interface type and selected channel (if any)
|
||||
if self.rf_channel_width:
|
||||
@ -803,8 +801,6 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
|
||||
raise ValidationError({'rf_channel_width': "Channel width may be set only on wireless interfaces."})
|
||||
if self.rf_channel and self.rf_channel_width != get_channel_attr(self.rf_channel, 'width'):
|
||||
raise ValidationError({'rf_channel_width': "Cannot specify custom width with channel selected."})
|
||||
elif self.rf_channel:
|
||||
self.rf_channel_width = get_channel_attr(self.rf_channel, 'width')
|
||||
|
||||
# VLAN validation
|
||||
|
||||
@ -815,6 +811,16 @@ class Interface(ModularComponentModel, BaseInterface, CabledObjectModel, PathEnd
|
||||
f"interface's parent device, or it must be global."
|
||||
})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
# Set absolute channel attributes from selected options
|
||||
if self.rf_channel and not self.rf_channel_frequency:
|
||||
self.rf_channel_frequency = get_channel_attr(self.rf_channel, 'frequency')
|
||||
if self.rf_channel and not self.rf_channel_width:
|
||||
self.rf_channel_width = get_channel_attr(self.rf_channel, 'width')
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def _occupied(self):
|
||||
return super()._occupied or bool(self.wireless_link_id)
|
||||
|
@ -222,8 +222,6 @@ class Rack(PrimaryModel, WeightMixin):
|
||||
# Validate outer dimensions and unit
|
||||
if (self.outer_width is not None or self.outer_depth is not None) and not self.outer_unit:
|
||||
raise ValidationError("Must specify a unit when setting an outer width/depth")
|
||||
elif self.outer_width is None and self.outer_depth is None:
|
||||
self.outer_unit = ''
|
||||
|
||||
# Validate max_weight and weight_unit
|
||||
if self.max_weight and not self.weight_unit:
|
||||
@ -259,6 +257,10 @@ class Rack(PrimaryModel, WeightMixin):
|
||||
else:
|
||||
self._abs_max_weight = None
|
||||
|
||||
# Clear unit if outer width & depth are not set
|
||||
if self.outer_width is None and self.outer_depth is None:
|
||||
self.outer_unit = ''
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
|
@ -178,9 +178,6 @@ class Aggregate(GetAvailablePrefixesMixin, PrimaryModel):
|
||||
|
||||
if self.prefix:
|
||||
|
||||
# Clear host bits from prefix
|
||||
self.prefix = self.prefix.cidr
|
||||
|
||||
# /0 masks are not acceptable
|
||||
if self.prefix.prefixlen == 0:
|
||||
raise ValidationError({
|
||||
|
@ -169,8 +169,6 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
|
||||
raise ValidationError({
|
||||
'cluster': f'The selected cluster ({self.cluster}) is not assigned to this site ({self.site}).'
|
||||
})
|
||||
elif self.cluster:
|
||||
self.site = self.cluster.site
|
||||
|
||||
# Validate assigned cluster device
|
||||
if self.device and not self.cluster:
|
||||
@ -201,6 +199,14 @@ class VirtualMachine(PrimaryModel, ConfigContextModel):
|
||||
field: f"The specified IP address ({ip}) is not assigned to this VM.",
|
||||
})
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
|
||||
# Assign site from cluster if not set
|
||||
if self.cluster and not self.site:
|
||||
self.site = self.cluster.site
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
def get_status_color(self):
|
||||
return VirtualMachineStatusChoices.colors.get(self.status)
|
||||
|
||||
|
@ -72,7 +72,7 @@ class VirtualMachineTestCase(TestCase):
|
||||
|
||||
# VM with cluster site but no direct site should have its site set automatically
|
||||
vm = VirtualMachine(name='vm1', site=None, cluster=clusters[0])
|
||||
vm.full_clean()
|
||||
vm.save()
|
||||
self.assertEqual(vm.site, sites[0])
|
||||
|
||||
def test_vm_name_case_sensitivity(self):
|
||||
|
Reference in New Issue
Block a user