Просмотр исходного кода

Closes #21259: Cache ObjectType results for the duration of a request (#21287)

Jeremy Stretch 2 недель назад
Родитель
Сommit
8f5f91fcfe
3 измененных файлов с 17 добавлено и 1 удалено
  1. 11 0
      netbox/core/models/object_types.py
  2. 2 0
      netbox/netbox/context.py
  3. 4 1
      netbox/netbox/context_managers.py

+ 11 - 0
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 query_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 = query_cache.get()
+        if cache is not None:
+            if ot := cache['object_types'].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['object_types'][(model._meta.model, for_concrete_model)] = ot
+
         return ot
 
     def get_for_models(self, *models, for_concrete_models=True):

+ 2 - 0
netbox/netbox/context.py

@@ -3,8 +3,10 @@ from contextvars import ContextVar
 __all__ = (
     'current_request',
     'events_queue',
+    'query_cache',
 )
 
 
 current_request = ContextVar('current_request', default=None)
 events_queue = ContextVar('events_queue', default=dict())
+query_cache = ContextVar('query_cache', default=None)

+ 4 - 1
netbox/netbox/context_managers.py

@@ -1,6 +1,7 @@
+from collections import defaultdict
 from contextlib import contextmanager
 
-from netbox.context import current_request, events_queue
+from netbox.context import current_request, events_queue, query_cache
 from netbox.utils import register_request_processor
 from extras.events import flush_events
 
@@ -16,6 +17,7 @@ def event_tracking(request):
     """
     current_request.set(request)
     events_queue.set({})
+    query_cache.set(defaultdict(dict))
 
     yield
 
@@ -26,3 +28,4 @@ def event_tracking(request):
     # Clear context vars
     current_request.set(None)
     events_queue.set({})
+    query_cache.set(None)