mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-31 04:46:26 -06:00
9604 add scope type to CircuitTermination
This commit is contained in:
parent
f1a62f3a6a
commit
cfdbd74e94
@ -26,37 +26,37 @@ __all__ = (
|
|||||||
class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
|
class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
|
||||||
region_id = TreeNodeMultipleChoiceFilter(
|
region_id = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
field_name='circuits__terminations__site__region',
|
field_name='circuits__terminations___site__region',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
label=_('Region (ID)'),
|
label=_('Region (ID)'),
|
||||||
)
|
)
|
||||||
region = TreeNodeMultipleChoiceFilter(
|
region = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
field_name='circuits__terminations__site__region',
|
field_name='circuits__terminations___site__region',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('Region (slug)'),
|
label=_('Region (slug)'),
|
||||||
)
|
)
|
||||||
site_group_id = TreeNodeMultipleChoiceFilter(
|
site_group_id = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
field_name='circuits__terminations__site__group',
|
field_name='circuits__terminations___site__group',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
label=_('Site group (ID)'),
|
label=_('Site group (ID)'),
|
||||||
)
|
)
|
||||||
site_group = TreeNodeMultipleChoiceFilter(
|
site_group = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
field_name='circuits__terminations__site__group',
|
field_name='circuits__terminations___site__group',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('Site group (slug)'),
|
label=_('Site group (slug)'),
|
||||||
)
|
)
|
||||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='circuits__terminations__site',
|
field_name='circuits__terminations___site',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
label=_('Site'),
|
label=_('Site'),
|
||||||
)
|
)
|
||||||
site = django_filters.ModelMultipleChoiceFilter(
|
site = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='circuits__terminations__site__slug',
|
field_name='circuits__terminations___site__slug',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('Site (slug)'),
|
label=_('Site (slug)'),
|
||||||
@ -193,37 +193,37 @@ class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilte
|
|||||||
)
|
)
|
||||||
region_id = TreeNodeMultipleChoiceFilter(
|
region_id = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
field_name='terminations__site__region',
|
field_name='terminations___site__region',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
label=_('Region (ID)'),
|
label=_('Region (ID)'),
|
||||||
)
|
)
|
||||||
region = TreeNodeMultipleChoiceFilter(
|
region = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=Region.objects.all(),
|
queryset=Region.objects.all(),
|
||||||
field_name='terminations__site__region',
|
field_name='terminations___site__region',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('Region (slug)'),
|
label=_('Region (slug)'),
|
||||||
)
|
)
|
||||||
site_group_id = TreeNodeMultipleChoiceFilter(
|
site_group_id = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
field_name='terminations__site__group',
|
field_name='terminations___site__group',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
label=_('Site group (ID)'),
|
label=_('Site group (ID)'),
|
||||||
)
|
)
|
||||||
site_group = TreeNodeMultipleChoiceFilter(
|
site_group = TreeNodeMultipleChoiceFilter(
|
||||||
queryset=SiteGroup.objects.all(),
|
queryset=SiteGroup.objects.all(),
|
||||||
field_name='terminations__site__group',
|
field_name='terminations___site__group',
|
||||||
lookup_expr='in',
|
lookup_expr='in',
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('Site group (slug)'),
|
label=_('Site group (slug)'),
|
||||||
)
|
)
|
||||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='terminations__site',
|
field_name='terminations___site',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
label=_('Site (ID)'),
|
label=_('Site (ID)'),
|
||||||
)
|
)
|
||||||
site = django_filters.ModelMultipleChoiceFilter(
|
site = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='terminations__site__slug',
|
field_name='terminations___site__slug',
|
||||||
queryset=Site.objects.all(),
|
queryset=Site.objects.all(),
|
||||||
to_field_name='slug',
|
to_field_name='slug',
|
||||||
label=_('Site (slug)'),
|
label=_('Site (slug)'),
|
||||||
@ -263,16 +263,16 @@ class CircuitTerminationFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet):
|
|||||||
queryset=Circuit.objects.all(),
|
queryset=Circuit.objects.all(),
|
||||||
label=_('Circuit'),
|
label=_('Circuit'),
|
||||||
)
|
)
|
||||||
site_id = django_filters.ModelMultipleChoiceFilter(
|
# site_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=Site.objects.all(),
|
# queryset=Site.objects.all(),
|
||||||
label=_('Site (ID)'),
|
# label=_('Site (ID)'),
|
||||||
)
|
# )
|
||||||
site = django_filters.ModelMultipleChoiceFilter(
|
# site = django_filters.ModelMultipleChoiceFilter(
|
||||||
field_name='site__slug',
|
# field_name='site__slug',
|
||||||
queryset=Site.objects.all(),
|
# queryset=Site.objects.all(),
|
||||||
to_field_name='slug',
|
# to_field_name='slug',
|
||||||
label=_('Site (slug)'),
|
# label=_('Site (slug)'),
|
||||||
)
|
# )
|
||||||
provider_network_id = django_filters.ModelMultipleChoiceFilter(
|
provider_network_id = django_filters.ModelMultipleChoiceFilter(
|
||||||
queryset=ProviderNetwork.objects.all(),
|
queryset=ProviderNetwork.objects.all(),
|
||||||
label=_('ProviderNetwork (ID)'),
|
label=_('ProviderNetwork (ID)'),
|
||||||
|
@ -1,14 +1,27 @@
|
|||||||
# Generated by Django 5.0.9 on 2024-10-21 17:15
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def copy_site_assignments(apps, schema_editor):
|
||||||
|
"""
|
||||||
|
Copy site ForeignKey values to the scope GFK.
|
||||||
|
"""
|
||||||
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||||
|
CircuitTermination = apps.get_model('circuits', 'CircuitTermination')
|
||||||
|
Site = apps.get_model('dcim', 'Site')
|
||||||
|
|
||||||
|
CircuitTermination.objects.filter(site__isnull=False).update(
|
||||||
|
scope_type=ContentType.objects.get_for_model(Site),
|
||||||
|
scope_id=models.F('site_id')
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('circuits', '0045_circuit_distance'),
|
('circuits', '0045_circuit_distance'),
|
||||||
('contenttypes', '0002_remove_content_type_name'),
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
('dcim', '0193_poweroutlet_color'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
@ -29,4 +42,10 @@ class Migration(migrations.Migration):
|
|||||||
to='contenttypes.contenttype',
|
to='contenttypes.contenttype',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
# Copy over existing site assignments
|
||||||
|
migrations.RunPython(
|
||||||
|
code=copy_site_assignments,
|
||||||
|
reverse_code=migrations.RunPython.noop
|
||||||
|
),
|
||||||
]
|
]
|
@ -0,0 +1,85 @@
|
|||||||
|
# Generated by Django 5.0.9 on 2024-10-21 17:34
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
def populate_denormalized_fields(apps, schema_editor):
|
||||||
|
"""
|
||||||
|
Copy site ForeignKey values to the scope GFK.
|
||||||
|
"""
|
||||||
|
CircuitTermination = apps.get_model('circuits', 'CircuitTermination')
|
||||||
|
|
||||||
|
terminations = CircuitTermination.objects.filter(site__isnull=False).prefetch_related('site')
|
||||||
|
for termination in terminations:
|
||||||
|
termination._region_id = termination.site.region_id
|
||||||
|
termination._sitegroup_id = termination.site.group_id
|
||||||
|
termination._site_id = termination.site_id
|
||||||
|
# Note: Location cannot be set prior to migration
|
||||||
|
|
||||||
|
CircuitTermination.objects.bulk_update(terminations, ['_region', '_sitegroup', '_site'])
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('circuits', '0046_circuittermination__scope'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='circuittermination',
|
||||||
|
name='_location',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
to='dcim.location',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='circuittermination',
|
||||||
|
name='_region',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
to='dcim.region',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='circuittermination',
|
||||||
|
name='_site',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
to='dcim.site',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='circuittermination',
|
||||||
|
name='_sitegroup',
|
||||||
|
field=models.ForeignKey(
|
||||||
|
blank=True,
|
||||||
|
null=True,
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
to='dcim.sitegroup',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
|
||||||
|
# Populate denormalized FK values
|
||||||
|
migrations.RunPython(
|
||||||
|
code=populate_denormalized_fields,
|
||||||
|
reverse_code=migrations.RunPython.noop
|
||||||
|
),
|
||||||
|
|
||||||
|
# Delete the site ForeignKey
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='circuittermination',
|
||||||
|
name='site',
|
||||||
|
),
|
||||||
|
]
|
@ -250,13 +250,13 @@ class CircuitTermination(
|
|||||||
ct_field='scope_type',
|
ct_field='scope_type',
|
||||||
fk_field='scope_id'
|
fk_field='scope_id'
|
||||||
)
|
)
|
||||||
site = models.ForeignKey(
|
# site = models.ForeignKey(
|
||||||
to='dcim.Site',
|
# to='dcim.Site',
|
||||||
on_delete=models.PROTECT,
|
# on_delete=models.PROTECT,
|
||||||
related_name='circuit_terminations',
|
# related_name='circuit_terminations',
|
||||||
blank=True,
|
# blank=True,
|
||||||
null=True
|
# null=True
|
||||||
)
|
# )
|
||||||
provider_network = models.ForeignKey(
|
provider_network = models.ForeignKey(
|
||||||
to='circuits.ProviderNetwork',
|
to='circuits.ProviderNetwork',
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
@ -294,6 +294,36 @@ class CircuitTermination(
|
|||||||
blank=True
|
blank=True
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Cached associations to enable efficient filtering
|
||||||
|
_location = models.ForeignKey(
|
||||||
|
to='dcim.Location',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
_site = models.ForeignKey(
|
||||||
|
to='dcim.Site',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
_region = models.ForeignKey(
|
||||||
|
to='dcim.Region',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
_sitegroup = models.ForeignKey(
|
||||||
|
to='dcim.SiteGroup',
|
||||||
|
on_delete=models.CASCADE,
|
||||||
|
related_name='_circuit_terminations',
|
||||||
|
blank=True,
|
||||||
|
null=True
|
||||||
|
)
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['circuit', 'term_side']
|
ordering = ['circuit', 'term_side']
|
||||||
constraints = (
|
constraints = (
|
||||||
|
Loading…
Reference in New Issue
Block a user