views:

240

answers:

1

I've got a view in Django that uses memcached to cache data for the more highly trafficked views that rely on a relatively static set of data. The key word is relatively: I need invalidate the memcached key for that particular URL's data when it's changed in the database. To be as clear as possible, here's the meat an' potatoes of the view (Person is a model, cache is django.core.cache.cache):

def person_detail(request, slug): 
    if request.is_ajax():
        cache_key = "%s_ABOUT_%s" % settings.SITE_PREFIX, slug

        # Check the cache to see if we've already got this result made.
        json_dict = cache.get(cache_key)

        # Was it a cache hit?
        if json_dict is None:
            # That's a negative Ghost Rider
            person = get_object_or_404(Person, display = True, slug = slug)

            json_dict = {
                'name' : person.name,
                'bio' : person.bio_html,
                'image' : person.image.extra_thumbnails['large'].absolute_url,
            }

            cache.set(cache_key)

        # json_dict will now exist, whether it's from the cache or not
        response = HttpResponse()
        response['Content-Type'] = 'text/javascript'
        response.write(simpljson.dumps(json_dict)) # Make sure it's all properly formatted for JS by using simplejson
        return response
    else:
        # This is where the fully templated response is generated

What I want to do is get at that cache_key variable in it's "unformatted" form, but I'm not sure how to do this--if it can be done at all.

Just in case there's already something to do this, here's what I want to do with it (this is from the Person model's hypothetical save method)

def save(self):    
    # If this is an update, the key will be cached, otherwise it won't, let's see if we can't find me
    try:
        old_self = Person.objects.get(pk=self.id)
        cache_key = # Voodoo magic to get that variable
        old_key = cache_key.format(settings.SITE_PREFIX, old_self.slug) # Generate the key currently cached
        cache.delete(old_key) # Hit it with both barrels of rock salt

    # Turns out this  doesn't already exist, let's make that first request even faster by making this cache right now
    except DoesNotExist:
        # I haven't gotten to this yet.

    super(Person, self).save()

I'm thinking about making a view class for this sorta stuff, and having functions in it like remove_cache or generate_cache since I do this sorta stuff a lot. Would that be a better idea? If so, how would I call the views in the URLconf if they're in a class?

+1  A: 

URLConf should point to any callable. There's no strict requirement to make it point to function exactly. You could implement base class with your cache methods then extend it:

class RealView(BaseViewWithCacheMethods):
    def __call__(self, request):
        if request.is_ajax():
            return self.ajax_view()
        return self.html_view()

URLConf definition would be something like that:

from django.conf.urls.defaults import *
from views import RealView

urlpattrens = patterns('',
    (r'^$', RealView()),
)
uptimebox
This is the approach I've been taking so far, limited success and very in-progress. I'll post the Class here once I'm done with it.
Zack