mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-28 10:16:10 -06:00
This commit is contained in:
parent
d5e49c8cb0
commit
66140fc017
@ -53,8 +53,26 @@ class VRFView(GetRelatedModelsMixin, generic.ObjectView):
|
|||||||
)
|
)
|
||||||
export_targets_table.configure(request)
|
export_targets_table.configure(request)
|
||||||
|
|
||||||
|
related_models = self.get_related_models(
|
||||||
|
request,
|
||||||
|
instance,
|
||||||
|
omit=(Interface, VMInterface),
|
||||||
|
extra=(
|
||||||
|
(
|
||||||
|
Interface.objects.restrict(request.user, 'view').filter(vrf=instance),
|
||||||
|
'vrf_id',
|
||||||
|
_('Device Interfaces')
|
||||||
|
),
|
||||||
|
(
|
||||||
|
VMInterface.objects.restrict(request.user, 'view').filter(vrf=instance),
|
||||||
|
'vrf_id',
|
||||||
|
_('VM Interfaces')
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'related_models': self.get_related_models(request, instance, omit=[Interface, VMInterface]),
|
'related_models': related_models,
|
||||||
'import_targets_table': import_targets_table,
|
'import_targets_table': import_targets_table,
|
||||||
'export_targets_table': export_targets_table,
|
'export_targets_table': export_targets_table,
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
<div class="card">
|
<div class="card">
|
||||||
<h2 class="card-header">{% trans "Related Objects" %}</h2>
|
<h2 class="card-header">{% trans "Related Objects" %}</h2>
|
||||||
<ul class="list-group list-group-flush" role="presentation">
|
<ul class="list-group list-group-flush" role="presentation">
|
||||||
{% for qs, filter_param in related_models %}
|
{% for related_object_count in related_models %}
|
||||||
{% with viewname=qs.model|validated_viewname:"list" %}
|
{% with viewname=related_object_count.queryset.model|validated_viewname:"list" %}
|
||||||
{% if viewname is not None %}
|
{% if viewname is not None %}
|
||||||
<a href="{% url viewname %}?{{ filter_param }}={{ object.pk }}" class="list-group-item list-group-item-action d-flex justify-content-between">
|
<a href="{% url viewname %}?{{ related_object_count.filter_param }}={{ object.pk }}" class="list-group-item list-group-item-action d-flex justify-content-between">
|
||||||
{{ qs.model|meta:"verbose_name_plural"|bettertitle }}
|
{{ related_object_count.name }}
|
||||||
{% with count=qs.count %}
|
{% with count=related_object_count.queryset.count %}
|
||||||
{% if count %}
|
{% if count %}
|
||||||
<span class="badge text-bg-primary rounded-pill">{{ count }}</span>
|
<span class="badge text-bg-primary rounded-pill">{{ count }}</span>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib.auth.mixins import AccessMixin
|
from django.contrib.auth.mixins import AccessMixin
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.db.models import QuerySet
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.urls.exceptions import NoReverseMatch
|
from django.urls.exceptions import NoReverseMatch
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
@ -12,6 +14,7 @@ from netbox.plugins import PluginConfig
|
|||||||
from netbox.registry import registry
|
from netbox.registry import registry
|
||||||
from utilities.relations import get_related_models
|
from utilities.relations import get_related_models
|
||||||
from utilities.request import safe_for_redirect
|
from utilities.request import safe_for_redirect
|
||||||
|
from utilities.string import title
|
||||||
from .permissions import resolve_permission
|
from .permissions import resolve_permission
|
||||||
|
|
||||||
__all__ = (
|
__all__ = (
|
||||||
@ -177,8 +180,17 @@ class GetRelatedModelsMixin:
|
|||||||
"""
|
"""
|
||||||
Provides logic for collecting all related models for the currently viewed model.
|
Provides logic for collecting all related models for the currently viewed model.
|
||||||
"""
|
"""
|
||||||
|
@dataclass
|
||||||
|
class RelatedObjectCount:
|
||||||
|
queryset: QuerySet
|
||||||
|
filter_param: str
|
||||||
|
label: str = ''
|
||||||
|
|
||||||
def get_related_models(self, request, instance, omit=[], extra=[]):
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self.label or title(_(self.queryset.model._meta.verbose_name_plural))
|
||||||
|
|
||||||
|
def get_related_models(self, request, instance, omit=None, extra=None):
|
||||||
"""
|
"""
|
||||||
Get related models of the view's `queryset` model without those listed in `omit`. Will be sorted alphabetical.
|
Get related models of the view's `queryset` model without those listed in `omit`. Will be sorted alphabetical.
|
||||||
|
|
||||||
@ -191,6 +203,7 @@ class GetRelatedModelsMixin:
|
|||||||
extra: Add extra models to the list of automatically determined related models. Can be used to add indirect
|
extra: Add extra models to the list of automatically determined related models. Can be used to add indirect
|
||||||
relationships.
|
relationships.
|
||||||
"""
|
"""
|
||||||
|
omit = omit or []
|
||||||
model = self.queryset.model
|
model = self.queryset.model
|
||||||
related = filter(
|
related = filter(
|
||||||
lambda m: m[0] is not model and m[0] not in omit,
|
lambda m: m[0] is not model and m[0] not in omit,
|
||||||
@ -198,7 +211,7 @@ class GetRelatedModelsMixin:
|
|||||||
)
|
)
|
||||||
|
|
||||||
related_models = [
|
related_models = [
|
||||||
(
|
self.RelatedObjectCount(
|
||||||
model.objects.restrict(request.user, 'view').filter(**(
|
model.objects.restrict(request.user, 'view').filter(**(
|
||||||
{f'{field}__in': instance}
|
{f'{field}__in': instance}
|
||||||
if isinstance(instance, Iterable)
|
if isinstance(instance, Iterable)
|
||||||
@ -208,11 +221,14 @@ class GetRelatedModelsMixin:
|
|||||||
)
|
)
|
||||||
for model, field in related
|
for model, field in related
|
||||||
]
|
]
|
||||||
related_models.extend(extra)
|
if extra is not None:
|
||||||
|
related_models.extend([
|
||||||
|
self.RelatedObjectCount(*attrs) for attrs in extra
|
||||||
|
])
|
||||||
|
|
||||||
return sorted(
|
return sorted(
|
||||||
filter(lambda qs: qs[0].exists(), related_models),
|
filter(lambda roc: roc.queryset.exists(), related_models),
|
||||||
key=lambda qs: qs[0].model._meta.verbose_name.lower(),
|
key=lambda roc: roc.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user