class cached_property(object, name) [source]
The @cached_property decorator caches the result of a method with a single self argument as a property. The cached result will persist as long as the instance does, so if the instance is passed around and the function subsequently invoked, the cached result will be returned.
Consider a typical case, where a view might need to call a model’s method to perform some computation, before placing the model instance into the context, where the template might invoke the method once more:
# the model
class Person(models.Model):
def friends(self):
# expensive computation
...
return friends
# in the view:
if person.friends():
...
And in the template you would have:
{% for friend in person.friends %}
Here, friends() will be called twice. Since the instance person in the view and the template are the same, @cached_property can avoid that:
from django.utils.functional import cached_property
@cached_property
def friends(self):
# expensive computation
...
return friends
Note that as the method is now a property, in Python code it will need to be invoked appropriately:
# in the view:
if person.friends:
...
The cached value can be treated like an ordinary attribute of the instance:
# clear it, requiring re-computation next time it's called del person.friends # or delattr(person, "friends") # set a value manually, that will persist on the instance until cleared person.friends = ["Huckleberry Finn", "Tom Sawyer"]
As well as offering potential performance advantages, @cached_property can ensure that an attribute’s value does not change unexpectedly over the life of an instance. This could occur with a method whose computation is based on datetime.now(), or simply if a change were saved to the database by some other process in the brief interval between subsequent invocations of a method on the same instance.
You can use the name argument to make cached properties of other methods. For example, if you had an expensive get_friends() method and wanted to allow calling it without retrieving the cached value, you could write:
friends = cached_property(get_friends, name='friends')
While person.get_friends() will recompute the friends on each call, the value of the cached property will persist until you delete it as described above:
x = person.friends # calls first time y = person.get_friends() # calls again z = person.friends # does not call x is z # is True
Please login to continue.