mirror of
https://github.com/netbox-community/netbox.git
synced 2026-01-21 02:58:43 -06:00
15794 Make "related objects" dynamic (#15876)
* Closes #15794: Make "related objects" dynamic Instead of hardcoding relationships between models for the detail view, they are now dynamically generated. * Fix related models call * 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. * Fix relations view for ASNs ASNs have ManyToMany relationships and therefore can't used automatic resolving. Explicit relations have been restored as before. * Add method call keywords for clarification * Cleanup related models --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
from typing import Iterable
|
||||
|
||||
from django.contrib.auth.mixins import AccessMixin
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.urls import reverse
|
||||
@@ -6,10 +8,12 @@ from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from netbox.plugins import PluginConfig
|
||||
from netbox.registry import registry
|
||||
from utilities.relations import get_related_models
|
||||
from .permissions import resolve_permission
|
||||
|
||||
__all__ = (
|
||||
'ContentTypePermissionRequiredMixin',
|
||||
'GetRelatedModelsMixin',
|
||||
'GetReturnURLMixin',
|
||||
'ObjectPermissionRequiredMixin',
|
||||
'ViewTab',
|
||||
@@ -142,6 +146,46 @@ class GetReturnURLMixin:
|
||||
return reverse('home')
|
||||
|
||||
|
||||
class GetRelatedModelsMixin:
|
||||
"""
|
||||
Provides logic for collecting all related models for the currently viewed model.
|
||||
"""
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
request: Current request being processed.
|
||||
instance: The instance related models should be looked up for. A list of instances can be passed to match
|
||||
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(
|
||||
lambda m: m[0] is not model and m[0] not in omit,
|
||||
get_related_models(model, False)
|
||||
)
|
||||
|
||||
related_models = [
|
||||
(
|
||||
model.objects.restrict(request.user, 'view').filter(**(
|
||||
{f'{field}__in': instance}
|
||||
if isinstance(instance, Iterable)
|
||||
else {field: instance}
|
||||
)),
|
||||
f'{field}_id'
|
||||
)
|
||||
for model, field in related
|
||||
]
|
||||
related_models.extend(extra)
|
||||
|
||||
return sorted(related_models, key=lambda x: x[0].model._meta.verbose_name.lower())
|
||||
|
||||
|
||||
class ViewTab:
|
||||
"""
|
||||
ViewTabs are used for navigation among multiple object-specific views, such as the changelog or journal for
|
||||
|
||||
Reference in New Issue
Block a user