djangodjango-caching

Can not iterate over results of a cached queryset in Django


I'd like to cache only the comments section of each article without caching the whole page, so the article views, I have

try:
    cmnts_key = post_slug
    comments = cache.get(cmnts_key)
    if not comments:
        comments = Comment.objects.filter(post=post).order_by("created")
        cache.set(cmnts_key, comments, COMMENTS_CACHE_TIMEOUT)
except: 
    print 'comments fetch exception'
    pass

...
args = {}
args['post'] = post
args['comments'] = comments
return render(request, "post.html", args)

However in the template where it tries to render comments {% for comment in comments %} I get:

'Article' object is not iterable.

I don't know whether it is principally impossible to iterate over cached query set results or there is a problem is my code, and if so, how can I fix it?

UPDATE. Here is my comment model:

class Comment(models.Model):
    author = models.ForeignKey(User)
    created = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=100, default='', blank=True)
    body = models.TextField()
    post = models.ForeignKey(Article)
    published = models.BooleanField(default=True)


    def __unicode__(self):
        return unicode("%s: %s" % (self.post, self.body[:60]))

    def get_absolute_url(self):
        return "/article/"+ self.slug     

    def save(self, *args, **kwargs):
        self.title = comment_truncate(self.body)        
        super(Comment, self).save(*args, **kwargs)

    @property
    def cache_key(self):
        return self.get_absolute_url()

Solution

  • You seem to be using the article slug as the key to get/set the comments in the cache. I guess that elsewhere, in code you haven't shown, you're using that same key to cache an actual Article (which would make sense), and that's what you're retrieving in this code.

    You might want to disambiguate them by using "comments:%s" % post_slug as the cache key.