Reputation: 1
I can use these cache methods set(), get(), touch(), incr(), decr(), incr_version(), decr_version(), delete(), delete_many(), clear() and close() as shown below:
from django.core.cache import cache
cache.set("first_name", "John")
cache.set("last_name", "Smith")
cache.set_many({"age": 36, "gender": "Male"})
cache.get("first_name")
cache.get_or_set("last_name", "Doesn't exist")
cache.get_many(["age", "gender"])
cache.touch("first_name", 60)
cache.incr("age")
cache.decr("age")
cache.incr_version("first_name")
cache.decr_version("last_name")
cache.delete("first_name")
cache.delete_many(["last_name", "age"])
cache.clear()
cache.close()
But, dir() doesn't show these cache methods as shown below:
from django.core.cache import cache
print(dir(cache)) # Here
[
'__class__', '__contains__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattr__',
'__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__',
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__',
'_alias', '_connections'
]
So, how can I show these cache methods?
Upvotes: 1
Views: 65
Reputation: 477684
This is because the cache
is a proxy to the default cache, indeed [GitHub]:
class ConnectionProxy: # … def __getattr__(self, item): return getattr(self._connections[self._alias], item) # …
It thus will for a method, which is an attribute, fallback on __getattr__
, which will not then forward the item.
You can patch the __dir__
method through monkey patching:
from django.utils.connection import ConnectionProxy
def some_dir(self):
return dir(self._connections[self._alias])
ConnectionProxy.__dir__ = some_dir
for example in the ready
, this will then return the corresponding methods when using dir
.
Update: I made a pull request [GitHub] to patch the behavior for the ConnectionProxy
, although likely the same scenario will happen with all sorts of proxies and related design patterns throughout the code base.
Upvotes: 0
Reputation: 5785
You can show all those methods from BaseCache
and even see all other available attributes.
from django.core.cache.backends.base import BaseCache
dir(BaseCache)
['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__',
'__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'__weakref__', '_missing_key', 'aadd', 'aclear', 'aclose', 'add', 'adecr', 'adecr_version',
'adelete', 'adelete_many', 'aget', 'aget_many', 'aget_or_set', 'ahas_key', 'aincr',
'aincr_version', 'aset', 'aset_many', 'atouch', 'clear', 'close', 'decr', 'decr_version',
'delete', 'delete_many', 'get', 'get_backend_timeout', 'get_many', 'get_or_set', 'has_key',
'incr', 'incr_version', 'make_and_validate_key', 'make_key', 'set', 'set_many', 'touch',
'validate_key']
From source code doc,
Caching framework.
This package defines set of cache backends that all conform to a simple API. In a nutshell, a cache is a set of values -- which can be any object that may be pickled -- identified by string keys. For the complete API, see the abstract BaseCache class in django.core.cache.backends.base.
Upvotes: 1
Reputation: 33923
You can always have a look at the source code...
In this case it's because the cache
value that you import from here is actually a ConnectionProxy
object.
cache = ConnectionProxy(caches, DEFAULT_CACHE_ALIAS)
https://github.com/django/django/blob/main/django/utils/connection.py#L7
...and that object does not have any of those methods, instead it uses __getattr__
to 'proxy' uses of those attributes through to some other object instance.
def __getattr__(self, item):
return getattr(self._connections[self._alias], item)
Unless you set up some more complicated cache config, you can probably inspect those methods by doing:
dir(cache._connections["default"])
Upvotes: 1