diff options
author | Dan McGee <dan@archlinux.org> | 2010-09-14 17:42:12 -0500 |
---|---|---|
committer | Dan McGee <dan@archlinux.org> | 2010-09-14 17:42:12 -0500 |
commit | 5dc5688d971824f7ccc38c0d5f85f60743424c39 (patch) | |
tree | 2f1b83bc8f51eb007b4ebba477d75bc5d8b9d039 /feeds.py | |
parent | 6c54cdb9ca72c8745d76fe2d3db11197c9eb104d (diff) |
Improve request handling for feeds that haven't changed
By using the condition decorator (in a slightly odd way because these are
class-based views), we can cut down a lot on the response time for returning
304 status code for feeds that haven't changed. The decorator means we no
longer have to completely render the view to see if we can return a 304
status code.
Signed-off-by: Dan McGee <dan@archlinux.org>
Diffstat (limited to 'feeds.py')
-rw-r--r-- | feeds.py | 37 |
1 files changed, 37 insertions, 0 deletions
@@ -2,15 +2,36 @@ import datetime from django.contrib.syndication.views import Feed from django.db.models import Q +from django.utils.hashcompat import md5_constructor +from django.views.decorators.http import condition from main.models import Arch, Repo, Package from news.models import News +def package_etag(request, *args, **kwargs): + latest = Package.objects.latest('last_update') + if latest: + return md5_constructor( + str(kwargs) + str(latest.last_update)).hexdigest() + return None + +def package_last_modified(request, *args, **kwargs): + # we could break this down based on the request url, but it would probably + # cost us more in query time to do so. + latest = Package.objects.latest('last_update') + if latest: + return latest.last_update + return None + class PackageFeed(Feed): link = '/packages/' title_template = 'feeds/packages_title.html' description_template = 'feeds/packages_description.html' + def __call__(self, request, *args, **kwargs): + wrapper = condition(etag_func=package_etag, last_modified_func=package_last_modified) + return wrapper(super(PackageFeed, self).__call__)(request, *args, **kwargs) + def get_object(self, request, arch='', repo=''): obj = dict() qs = Package.objects.select_related('arch', 'repo').order_by('-last_update') @@ -57,6 +78,18 @@ class PackageFeed(Feed): return (item.repo.name, item.arch.name) +def news_etag(request, *args, **kwargs): + latest = News.objects.latest('last_modified') + if latest: + return md5_constructor(str(latest.last_modified)).hexdigest() + return None + +def news_last_modified(request): + latest = News.objects.latest('last_modified') + if latest: + return latest.last_modified + return None + class NewsFeed(Feed): title = 'Arch Linux: Recent news updates' link = '/news/' @@ -64,6 +97,10 @@ class NewsFeed(Feed): title_template = 'feeds/news_title.html' description_template = 'feeds/news_description.html' + def __call__(self, request, *args, **kwargs): + wrapper = condition(etag_func=news_etag, last_modified_func=news_last_modified) + return wrapper(super(NewsFeed, self).__call__)(request, *args, **kwargs) + def items(self): return News.objects.select_related('author').order_by('-postdate', '-id')[:10] |