diff --git a/netbox/core/models/object_types.py b/netbox/core/models/object_types.py index 21fbde3b3..a26712674 100644 --- a/netbox/core/models/object_types.py +++ b/netbox/core/models/object_types.py @@ -9,6 +9,7 @@ from django.db import connection, models from django.db.models import Q from django.utils.translation import gettext as _ +from netbox.context import object_types_cache from netbox.plugins import PluginConfig from netbox.registry import registry from utilities.string import title @@ -70,6 +71,12 @@ class ObjectTypeManager(models.Manager): """ from netbox.models.features import get_model_features, model_is_public + # Check the request cache before hitting the database + cache = object_types_cache.get() + if cache is not None: + if ot := cache.get((model._meta.model, for_concrete_model)): + return ot + # TODO: Remove this in NetBox v5.0 # If the ObjectType table has not yet been provisioned (e.g. because we're in a pre-v4.4 migration), # fall back to ContentType. @@ -96,6 +103,10 @@ class ObjectTypeManager(models.Manager): features=get_model_features(model), )[0] + # Populate the request cache to avoid redundant lookups + if cache is not None: + cache[(model._meta.model, for_concrete_model)] = ot + return ot def get_for_models(self, *models, for_concrete_models=True): diff --git a/netbox/netbox/context.py b/netbox/netbox/context.py index 744c36df4..9a27d1a4a 100644 --- a/netbox/netbox/context.py +++ b/netbox/netbox/context.py @@ -3,8 +3,10 @@ from contextvars import ContextVar __all__ = ( 'current_request', 'events_queue', + 'object_types_cache', ) current_request = ContextVar('current_request', default=None) events_queue = ContextVar('events_queue', default=dict()) +object_types_cache = ContextVar('object_types_cache', default=None) diff --git a/netbox/netbox/context_managers.py b/netbox/netbox/context_managers.py index 7b01cce94..4c3e2ff7b 100644 --- a/netbox/netbox/context_managers.py +++ b/netbox/netbox/context_managers.py @@ -1,6 +1,6 @@ from contextlib import contextmanager -from netbox.context import current_request, events_queue +from netbox.context import current_request, events_queue, object_types_cache from netbox.utils import register_request_processor from extras.events import flush_events @@ -16,6 +16,7 @@ def event_tracking(request): """ current_request.set(request) events_queue.set({}) + object_types_cache.set({}) yield @@ -26,3 +27,4 @@ def event_tracking(request): # Clear context vars current_request.set(None) events_queue.set({}) + object_types_cache.set(None)