Coverage for dcim/models/base.py: 71%
19 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-10 18:35 +0000
1from django.core.exceptions import ValidationError
2from django.core.validators import MaxValueValidator, MinValueValidator
3from django.db import models
4from django.utils.translation import gettext_lazy as _
6from dcim.constants import PORT_POSITION_MAX, PORT_POSITION_MIN
8__all__ = (
9 'PortMappingBase',
10)
13class PortMappingBase(models.Model):
14 """
15 Base class for PortMapping and PortTemplateMapping
16 """
17 front_port_position = models.PositiveSmallIntegerField(
18 default=1,
19 validators=(
20 MinValueValidator(PORT_POSITION_MIN),
21 MaxValueValidator(PORT_POSITION_MAX),
22 ),
23 )
24 rear_port_position = models.PositiveSmallIntegerField(
25 default=1,
26 validators=(
27 MinValueValidator(PORT_POSITION_MIN),
28 MaxValueValidator(PORT_POSITION_MAX),
29 ),
30 )
32 # Change-logged but private: no public API/URL, and the delete-time UPDATE cascade onto the
33 # parent ports stays suppressed (see #21390, #22270).
34 _netbox_private = True
36 class Meta:
37 abstract = True
38 constraints = (
39 models.UniqueConstraint(
40 fields=('front_port', 'front_port_position'),
41 name='%(app_label)s_%(class)s_unique_front_port_position'
42 ),
43 models.UniqueConstraint(
44 fields=('rear_port', 'rear_port_position'),
45 name='%(app_label)s_%(class)s_unique_rear_port_position'
46 ),
47 )
49 def __str__(self):
50 return f'{self.front_port}:{self.front_port_position} to {self.rear_port}:{self.rear_port_position}'
52 def clean(self):
53 super().clean()
55 # Validate rear port position
56 if self.rear_port_position > self.rear_port.positions:
57 raise ValidationError({
58 "rear_port_position": _(
59 "Invalid rear port position ({rear_port_position}): Rear port {name} has only {positions} "
60 "positions."
61 ).format(
62 rear_port_position=self.rear_port_position,
63 name=self.rear_port.name,
64 positions=self.rear_port.positions
65 )
66 })