23👍
You may be interested in a built-in django decorator django.utils.functional.memoize
.
Django uses this to cache expensive operation like url resolving.
18👍
Generally, I use a pattern like this:
def get_expensive_operation(self):
if not hasattr(self, '_expensive_operation'):
self._expensive_operation = self.expensive_operation()
return self._expensive_operation
Then you use the get_expensive_operation
method to access the data.
However, in your particular case, I think you are approaching this in slightly the wrong way. You need to do the deserialization when the model is first loaded from the database, and serialize on save only. Then you can simply access the attributes as a standard Python dictionary each time. You can do this by defining a custom JSONField type, subclassing models.TextField, which overrides to_python
and get_db_prep_save
.
In fact someone’s already done it: see here.
- Django REST Framework: Validate before a delete
- Why does Django South 1.0 use iteritems()?
- Django 1.6: How to access static files in view
2👍
For class methods, you should use django.utils.functional.cached_property
.
Since the first argument on a class method is self
, memoize
will maintain a reference to the object and the results of the function even after you’ve thrown it away. This can cause memory leaks by preventing the garbage collector from cleaning up the stale object. cached_property
turns Daniel’s suggestion into a decorator.