caching for item view
authorTero Marttila <terom@fixme.fi>
Sat, 07 Sep 2013 16:15:34 +0300
changeset 86 656c8ff72f77
parent 85 adddd20cec75
child 87 88d9c9974d6a
caching for item view
qrurls/models.py
qrurls/views.py
--- a/qrurls/models.py	Sat Sep 07 16:00:13 2013 +0300
+++ b/qrurls/models.py	Sat Sep 07 16:15:34 2013 +0300
@@ -189,7 +189,11 @@
         ordering = ['published']
 
     @classmethod
-    def get_item (cls, shorturl, item_id=None, related=()) :
+    def cache_key (cls, shorturl, item_id) :
+        return 'qrurls/url/{shorturl}/{item}'.format(shorturl=shorturl, item=item_id)
+
+    @classmethod
+    def get (cls, shorturl, item_id=None, related=()) :
         """
             Return the URLItem for a given shorturl, either the given specific one,
             or the latest, from the database.
@@ -213,7 +217,6 @@
        
         if item_id :
             # specific, but still the published on
-            item_id = int(item_id)
             log.debug("search @ %d", item_id)
 
             return url_item.get(id=item_id) # raises DoesNotExist
@@ -237,19 +240,49 @@
         get = cache.get(key)
         
         if get :
-            url, modified = get
-            log.debug("get cache: %s: %s", key, url)
+            log.debug("get cache: %s", key)
+            return get
         else:
             # from db
-            url_item = cls.get_item(shorturl=shorturl)
+            url_item = cls.get(shorturl=shorturl)
+            set = (
+                url_item.get_absolute_url(),
+                url_item.last_modified()
+            )
+            
+            log.debug("set cache: %s", key)
+            cache.set(key, set)
+            return set
 
-            url = url_item.get_absolute_url()
-            modified = url_item.last_modified()
-            
-            log.debug("set cache: %s: %s", key, url)
-            cache.set(key, (url, modified)) # XXX: expiry
-        
-        return url, modified
+    @classmethod
+    def get_item (cls, shorturl, item_id) :
+        """
+            Return a data dict for the given URLItem, from cache or DB.
+
+            Returns { url: str, title: str, image: str, last_modified: datetime }
+            Raises URLItem.NotFound
+        """
+
+        key = cls.cache_key(shorturl, item_id)
+        get = cache.get(key)
+
+        if get:
+            log.debug("cache get: %s", key)
+            return get
+        else:
+            url_item = URLItem.get(shorturl, item_id=item_id,
+                related=('shorturl', 'image'),
+            )
+            set = dict(
+                    url             = url_item.url,
+                    title           = url_item.title(),
+                    image           = url_item.image.get_absolute_url() if url_item.image else None,
+                    last_modified   = url_item.last_modified(),
+            )
+
+            log.debug("cache set: %s: %s", key, set)
+            cache.set(key, set)
+            return set
 
     def get_absolute_url (self) :
         if self.url :
@@ -309,4 +342,7 @@
     log.info("clear cache: %s: %s", instance, key)
     cache.delete(key)
 
+    key = URLItem.cache_key(instance.shorturl.shorturl, instance.id)
+    log.info("clear cache: %s: %s", instance, key)
+    cache.delete(key)
 
--- a/qrurls/views.py	Sat Sep 07 16:00:13 2013 +0300
+++ b/qrurls/views.py	Sat Sep 07 16:15:34 2013 +0300
@@ -42,26 +42,21 @@
     """
         Frontend for a specific item.
     """
-    
-    try :
-        url_item = URLItem.get_item(shorturl, item_id=item_id,
-            related=('shorturl', 'image'),
-        )
+
+    try:
+        data = URLItem.get_item(shorturl, int(item_id))
     except URLItem.DoesNotExist:
         raise Http404()
 
-    if url_item.url :
-        response = HttpResponseRedirect(url_item.url)
-    elif url_item.image :
-        response = render(request, 'qrurls/image.html', dict(
-            title   = url_item.title(),
-            image   = url_item.image.get_absolute_url(),
-        ))
+    if data['url'] :
+        response = HttpResponseRedirect(data['url'])
+    elif data['image'] :
+        response = render(request, 'qrurls/image.html', data)
     else :
         raise Http404()
 
     # set cache
     response['Vary'] = ''
-    response['Last-Modified'] = http_datetime(url_item.last_modified())
+    response['Last-Modified'] = data['last_modified']
     return response