Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions debug_toolbar/panels/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
]


def _monkey_patch_method(cache, name):
def _monkey_patch_method(cache, name, alias):
original_method = getattr(cache, name)

@functools.wraps(original_method)
Expand All @@ -39,16 +39,17 @@ def wrapper(*args, **kwargs):
if panel is None:
return original_method(*args, **kwargs)
else:
return panel._record_call(cache, name, original_method, args, kwargs)
return panel._record_call(cache, alias, name, original_method, args, kwargs)

setattr(cache, name, wrapper)


def _monkey_patch_cache(cache):
def _monkey_patch_cache(cache, alias, panel):
if not hasattr(cache, "_djdt_patched"):
for name in WRAPPED_CACHE_METHODS:
_monkey_patch_method(cache, name)
_monkey_patch_method(cache, name, alias)
cache._djdt_patched = True
cache._djdt_panel = panel


class CachePanel(Panel):
Expand Down Expand Up @@ -95,8 +96,7 @@ def wrapper(self, alias):
cache = original_method(self, alias)
panel = cls.current_instance()
if panel is not None:
_monkey_patch_cache(cache)
cache._djdt_panel = panel
_monkey_patch_cache(cache, alias, panel)
return cache

CacheHandler.create_connection = wrapper
Expand Down Expand Up @@ -138,7 +138,7 @@ def _store_call_info(
}
)

def _record_call(self, cache, name, original_method, args, kwargs):
def _record_call(self, cache, alias, name, original_method, args, kwargs):
# Some cache backends implement certain cache methods in terms of other cache
# methods (e.g. get_or_set() in terms of get() and add()). In order to only
# record the calls made directly by the user code, set the cache's _djdt_panel
Expand All @@ -161,7 +161,7 @@ def _record_call(self, cache, name, original_method, args, kwargs):
kwargs=kwargs,
trace=get_stack_trace(skip=2),
template_info=get_template_info(),
backend=cache,
backend=alias,
)
return value

Expand Down Expand Up @@ -194,9 +194,8 @@ def enable_instrumentation(self):
# requests. The monkey patch of CacheHander.create_connection() installed in
# the .ready() method will ensure that any new cache connections that get opened
# during this request will also be monkey patched.
for cache in caches.all(initialized_only=True):
_monkey_patch_cache(cache)
cache._djdt_panel = self
for cache, alias in self.initialized_caches():
_monkey_patch_cache(cache, alias, self)
# Mark this panel instance as the current one for the active thread/async task
# context. This will be used by the CacheHander.create_connection() monkey
# patch.
Expand All @@ -208,6 +207,17 @@ def disable_instrumentation(self):
for cache in caches.all(initialized_only=True):
cache._djdt_panel = None

def initialized_caches(self):
"""
Return the initialized caches and aliases.

This does the same as`caches.all(initialized_only=True)`, but keeps
the alias with each cache instance.
"""
for alias in caches:
if hasattr(caches._connections, alias):
yield caches[alias], alias

def generate_stats(self, request, response):
self.record_stats(
{
Expand Down
2 changes: 2 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ Pending
conflicts
* Added CSS for resetting the height of elements too to avoid problems with
global CSS of a website where the toolbar is used.
* Show the cache backend alias instead of the cache instance for each call in
the cache panel.

5.1.0 (2025-03-20)
------------------
Expand Down
4 changes: 4 additions & 0 deletions tests/panels/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,7 @@ def test_generate_server_timing(self):
}

self.assertEqual(self.panel.get_server_timing_stats(), expected_data)

def test_backend_alias_is_recorded(self):
cache.cache.get("foo")
self.assertEqual(self.panel.calls[0]["backend"], "default")
Loading