To make the management of cached data easier, bettercache provides a structured model for data caching, without the developer constantly building up ad-hoc key strings. This should be a familiar interface, fashioned after Django’s own database models.
class User(CacheModel):
username = Key()
email = Field()
full_name = Field()
user = User(
username = 'bob',
email = 'bob@hotmail.com',
full_name = 'Bob T Fredrick',
)
user.save()
...
user = User.get(username='bob')
user.email == 'bob@hotmail.com'
user.full_name == 'Bob T Fredrick'
CacheModel subclasses are a collection of Key and Field properties to populate with data to be stored in the cache. The creation of keys are automatic, based on the CacheModel class and the values given for all the Key fields for an instance.
The cache objects can save any fields with JSON-serializable values.
One useful CacheModel is included with bettercache, named bettercache.decorators.CachedMethod. This class acts as a decorator for methods, and will cache the results of those methods using a defined set of attributes from the instance. For any instance of the class with the same values for this set of attributes, the method will use the cached value properly, but also use its own parameters.
This is a decorator-factory, and it takes one required parameter and one optional.
@CachedMethod('attributes to cache on', expires=SECONDS)
class Home(object):
def __init__(self, address):
self.address = address
@CachedMethod('address')
def geocode(self):
return g.geocode(self.address)
An included CachedMethod decorator sublass which knows how to cache methods on Django forms, such that given the same form results, the methods will be cached from previous forms with the same results. This caches based on the cleaned_data rather than pre-validation data, so if your cleaning normalizes the input the caching will be more efficient.
class FriendsLookup(forms.Form):
username = forms.CharField(required=True)
@CachedFormMethod(expires=60*15) # expire in 15 minutes
def get_friends_list(self, include_pending=False):
username = self.cleaned_data['username']
friends = Friendship.objects.filter(
from_user__username=username)
if include_pending:
friends = friends.filter(status__in=(PENDING, APPROVED))
else:
friends = friends.filter(status=APPROVED)
return friends
When you define a CacheModel subclass, you can opt to implement the from_miss() method, which will be called on an instance of your class with the keys which couldn’t be found in the database.
Your from_miss() method should initialize the instance, after which the object will be saved to the cache and returned back from the original get() call in the first place.