diff --git a/netbox/circuits/constants.py b/netbox/circuits/constants.py new file mode 100644 index 000000000..827a46b91 --- /dev/null +++ b/netbox/circuits/constants.py @@ -0,0 +1,4 @@ +# models values for ContentTypes which may be CircuitTermination scope types +CIRCUIT_TERMINATION_SCOPE_TYPES = ( + 'region', 'sitegroup', 'site', 'location', +) diff --git a/netbox/circuits/migrations/0046_circuittermination_scope_id_and_more.py b/netbox/circuits/migrations/0046_circuittermination_scope_id_and_more.py new file mode 100644 index 000000000..5284ca93f --- /dev/null +++ b/netbox/circuits/migrations/0046_circuittermination_scope_id_and_more.py @@ -0,0 +1,32 @@ +# Generated by Django 5.0.9 on 2024-10-21 17:15 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('circuits', '0045_circuit_distance'), + ('contenttypes', '0002_remove_content_type_name'), + ] + + operations = [ + migrations.AddField( + model_name='circuittermination', + name='scope_id', + field=models.PositiveBigIntegerField(blank=True, null=True), + ), + migrations.AddField( + model_name='circuittermination', + name='scope_type', + field=models.ForeignKey( + blank=True, + limit_choices_to=models.Q(('model__in', ('region', 'sitegroup', 'site', 'location'))), + null=True, + on_delete=django.db.models.deletion.PROTECT, + related_name='+', + to='contenttypes.contenttype', + ), + ), + ] diff --git a/netbox/circuits/models/circuits.py b/netbox/circuits/models/circuits.py index 2df83e97e..01f35ea68 100644 --- a/netbox/circuits/models/circuits.py +++ b/netbox/circuits/models/circuits.py @@ -1,9 +1,12 @@ +from django.contrib.contenttypes.fields import GenericForeignKey from django.core.exceptions import ValidationError from django.db import models +from django.db.models import Q from django.urls import reverse from django.utils.translation import gettext_lazy as _ from circuits.choices import * +from circuits.constants import * from dcim.models import CabledObjectModel from netbox.models import ChangeLoggedModel, OrganizationalModel, PrimaryModel from netbox.models.mixins import DistanceMixin @@ -231,6 +234,22 @@ class CircuitTermination( choices=CircuitTerminationSideChoices, verbose_name=_('termination') ) + scope_type = models.ForeignKey( + to='contenttypes.ContentType', + on_delete=models.PROTECT, + limit_choices_to=Q(model__in=CIRCUIT_TERMINATION_SCOPE_TYPES), + related_name='+', + blank=True, + null=True + ) + scope_id = models.PositiveBigIntegerField( + blank=True, + null=True + ) + scope = GenericForeignKey( + ct_field='scope_type', + fk_field='scope_id' + ) site = models.ForeignKey( to='dcim.Site', on_delete=models.PROTECT,