Fixed #7936 -- Added Last-Modified header to feeds

Thanks julianb for the report and the initial patch, and Roman
Gladkov for working on tests.
This commit is contained in:
Claude Paroz 2012-09-30 20:44:27 +02:00
parent d0345b7114
commit 08d675a98f
4 changed files with 26 additions and 0 deletions

View File

@ -1,5 +1,7 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from calendar import timegm
from django.conf import settings from django.conf import settings
from django.contrib.sites.models import get_current_site from django.contrib.sites.models import get_current_site
from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
@ -8,6 +10,7 @@ from django.template import loader, TemplateDoesNotExist, RequestContext
from django.utils import feedgenerator, tzinfo from django.utils import feedgenerator, tzinfo
from django.utils.encoding import force_text, iri_to_uri, smart_text from django.utils.encoding import force_text, iri_to_uri, smart_text
from django.utils.html import escape from django.utils.html import escape
from django.utils.http import http_date
from django.utils.timezone import is_naive from django.utils.timezone import is_naive
@ -22,6 +25,7 @@ def add_domain(domain, url, secure=False):
url = iri_to_uri('%s://%s%s' % (protocol, domain, url)) url = iri_to_uri('%s://%s%s' % (protocol, domain, url))
return url return url
class FeedDoesNotExist(ObjectDoesNotExist): class FeedDoesNotExist(ObjectDoesNotExist):
pass pass
@ -38,6 +42,11 @@ class Feed(object):
raise Http404('Feed object does not exist.') raise Http404('Feed object does not exist.')
feedgen = self.get_feed(obj, request) feedgen = self.get_feed(obj, request)
response = HttpResponse(content_type=feedgen.mime_type) response = HttpResponse(content_type=feedgen.mime_type)
if hasattr(self, 'item_pubdate'):
# if item_pubdate is defined for the feed, set header so as
# ConditionalGetMiddleware is able to send 304 NOT MODIFIED
response['Last-Modified'] = http_date(
timegm(feedgen.latest_post_date().utctimetuple()))
feedgen.write(response, 'utf-8') feedgen.write(response, 'utf-8')
return response return response

View File

@ -46,6 +46,14 @@ class TestRss091Feed(TestRss2Feed):
feed_type = feedgenerator.RssUserland091Feed feed_type = feedgenerator.RssUserland091Feed
class TestNoPubdateFeed(views.Feed):
title = 'Test feed'
link = '/feed/'
def items(self):
return Entry.objects.all()
class TestAtomFeed(TestRss2Feed): class TestAtomFeed(TestRss2Feed):
feed_type = feedgenerator.Atom1Feed feed_type = feedgenerator.Atom1Feed
subtitle = TestRss2Feed.description subtitle = TestRss2Feed.description

View File

@ -226,6 +226,14 @@ class SyndicationFeedTest(FeedTestCase):
updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText
self.assertEqual(updated[-6:], '+00:42') self.assertEqual(updated[-6:], '+00:42')
def test_feed_last_modified_time(self):
response = self.client.get('/syndication/naive-dates/')
self.assertEqual(response['Last-Modified'], 'Thu, 03 Jan 2008 19:30:00 GMT')
# No last-modified when feed has no item_pubdate
response = self.client.get('/syndication/no_pubdate/')
self.assertFalse(response.has_header('Last-Modified'))
def test_feed_url(self): def test_feed_url(self):
""" """
Test that the feed_url can be overridden. Test that the feed_url can be overridden.

View File

@ -9,6 +9,7 @@ urlpatterns = patterns('django.contrib.syndication.views',
(r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()), (r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()),
(r'^syndication/rss2/$', feeds.TestRss2Feed()), (r'^syndication/rss2/$', feeds.TestRss2Feed()),
(r'^syndication/rss091/$', feeds.TestRss091Feed()), (r'^syndication/rss091/$', feeds.TestRss091Feed()),
(r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()),
(r'^syndication/atom/$', feeds.TestAtomFeed()), (r'^syndication/atom/$', feeds.TestAtomFeed()),
(r'^syndication/custom/$', feeds.TestCustomFeed()), (r'^syndication/custom/$', feeds.TestCustomFeed()),
(r'^syndication/naive-dates/$', feeds.NaiveDatesFeed()), (r'^syndication/naive-dates/$', feeds.NaiveDatesFeed()),