Remove extra related models hook

Instead of providing a rarely used hook method, additional related
models can now be passed directly to the lookup method.
This commit is contained in:
Alexander Haase 2024-05-15 23:05:21 +02:00
parent 6b13fec7b8
commit 1218bf188b
3 changed files with 50 additions and 48 deletions

View File

@ -150,17 +150,19 @@ class ProviderNetworkListView(generic.ObjectListView):
class ProviderNetworkView(GetRelatedModelsMixin, generic.ObjectView):
queryset = ProviderNetwork.objects.all()
def get_extra_related_models(self, request, instance):
return (
(
Circuit.objects.restrict(request.user, 'view').filter(terminations__provider_network=instance),
'provider_network_id',
),
)
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance, [CircuitTermination]),
'related_models': self.get_related_models(
request,
instance,
[CircuitTermination],
(
(
Circuit.objects.restrict(request.user, 'view').filter(terminations__provider_network=instance),
'provider_network_id',
),
),
),
}

View File

@ -229,17 +229,18 @@ class RegionListView(generic.ObjectListView):
class RegionView(GetRelatedModelsMixin, generic.ObjectView):
queryset = Region.objects.all()
def get_extra_related_models(self, request, regions):
return (
(Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
(Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
)
def get_extra_context(self, request, instance):
regions = instance.get_descendants(include_self=True)
return {
'related_models': self.get_related_models(request, regions),
'related_models': self.get_related_models(
request,
regions,
extra=(
(Location.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
(Rack.objects.restrict(request.user, 'view').filter(site__region__in=regions), 'region_id'),
),
),
}
@ -310,17 +311,18 @@ class SiteGroupListView(generic.ObjectListView):
class SiteGroupView(GetRelatedModelsMixin, generic.ObjectView):
queryset = SiteGroup.objects.all()
def get_extra_related_models(self, request, groups):
return (
(Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
(Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
)
def get_extra_context(self, request, instance):
groups = instance.get_descendants(include_self=True)
return {
'related_models': self.get_related_models(request, groups),
'related_models': self.get_related_models(
request,
groups,
extra=(
(Location.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
(Rack.objects.restrict(request.user, 'view').filter(site__group__in=groups), 'site_group_id'),
),
),
}
@ -385,18 +387,20 @@ class SiteListView(generic.ObjectListView):
class SiteView(GetRelatedModelsMixin, generic.ObjectView):
queryset = Site.objects.prefetch_related('tenant__group')
def get_extra_related_models(self, request, instance):
return (
(VLANGroup.objects.restrict(request.user, 'view').filter(
scope_type=ContentType.objects.get_for_model(Site),
scope_id=instance.pk
), 'site'),
(Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).distinct(), 'site_id'),
)
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance, [CableTermination, CircuitTermination]),
'related_models': self.get_related_models(
request,
instance,
[CableTermination, CircuitTermination],
(
(VLANGroup.objects.restrict(request.user, 'view').filter(
scope_type=ContentType.objects.get_for_model(Site),
scope_id=instance.pk
), 'site'),
(Circuit.objects.restrict(request.user, 'view').filter(terminations__site=instance).distinct(), 'site_id'),
),
),
}
@ -3598,14 +3602,15 @@ class VirtualDeviceContextListView(generic.ObjectListView):
class VirtualDeviceContextView(GetRelatedModelsMixin, generic.ObjectView):
queryset = VirtualDeviceContext.objects.all()
def get_extra_related_models(self, request, instance):
return (
(Interface.objects.restrict(request.user, 'view').filter(vdcs__in=[instance]), 'vdc_id'),
)
def get_extra_context(self, request, instance):
return {
'related_models': self.get_related_models(request, instance),
'related_models': self.get_related_models(
request,
instance,
extra=(
(Interface.objects.restrict(request.user, 'view').filter(vdcs__in=[instance]), 'vdc_id'),
),
),
}

View File

@ -151,14 +151,7 @@ class GetRelatedModelsMixin:
Provides logic for collecting all related models for the currently viewed model.
"""
def get_extra_related_models(self, request, instance):
"""
Get extra related models for `instance`, which extend `get_related_models`. Can be used to implement custom
lookups for nested and non-direct relationships.
"""
return []
def get_related_models(self, request, instance, omit=[]):
def get_related_models(self, request, instance, omit=[], extra=[]):
"""
Get related models of the view's `queryset` model without those listed in `omit`. Will be sorted alphabetical.
@ -168,6 +161,8 @@ class GetRelatedModelsMixin:
related objects in this list (e.g. to find sites of a region including child regions).
omit: Remove relationships to these models from the result. Needs to be passed, if related models don't
provide a `_list` view.
extra: Add extra models to the list of automatically determined related models. Can be used to add indirect
relationships.
"""
model = self.queryset.model
related = filter(
@ -186,7 +181,7 @@ class GetRelatedModelsMixin:
)
for model, field in related
]
related_models.extend(self.get_extra_related_models(request, instance))
related_models.extend(extra)
return sorted(related_models, key=lambda x: x[0].model._meta.verbose_name.lower())