From 08d675a98f1ae1d27f7e1946125ed5316c576802 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sun, 30 Sep 2012 20:44:27 +0200 Subject: [PATCH] Fixed #7936 -- Added Last-Modified header to feeds Thanks julianb for the report and the initial patch, and Roman Gladkov for working on tests. --- django/contrib/syndication/views.py | 9 +++++++++ tests/regressiontests/syndication/feeds.py | 8 ++++++++ tests/regressiontests/syndication/tests.py | 8 ++++++++ tests/regressiontests/syndication/urls.py | 1 + 4 files changed, 26 insertions(+) diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index 4815ce5567..996b7dfb40 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -1,5 +1,7 @@ from __future__ import unicode_literals +from calendar import timegm + from django.conf import settings from django.contrib.sites.models import get_current_site 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.encoding import force_text, iri_to_uri, smart_text from django.utils.html import escape +from django.utils.http import http_date 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)) return url + class FeedDoesNotExist(ObjectDoesNotExist): pass @@ -38,6 +42,11 @@ class Feed(object): raise Http404('Feed object does not exist.') feedgen = self.get_feed(obj, request) 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') return response diff --git a/tests/regressiontests/syndication/feeds.py b/tests/regressiontests/syndication/feeds.py index 748420c9d2..04a67f4bdb 100644 --- a/tests/regressiontests/syndication/feeds.py +++ b/tests/regressiontests/syndication/feeds.py @@ -46,6 +46,14 @@ class TestRss091Feed(TestRss2Feed): feed_type = feedgenerator.RssUserland091Feed +class TestNoPubdateFeed(views.Feed): + title = 'Test feed' + link = '/feed/' + + def items(self): + return Entry.objects.all() + + class TestAtomFeed(TestRss2Feed): feed_type = feedgenerator.Atom1Feed subtitle = TestRss2Feed.description diff --git a/tests/regressiontests/syndication/tests.py b/tests/regressiontests/syndication/tests.py index 1790d8cae6..10413b4ddd 100644 --- a/tests/regressiontests/syndication/tests.py +++ b/tests/regressiontests/syndication/tests.py @@ -226,6 +226,14 @@ class SyndicationFeedTest(FeedTestCase): updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText 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): """ Test that the feed_url can be overridden. diff --git a/tests/regressiontests/syndication/urls.py b/tests/regressiontests/syndication/urls.py index 2199e29f06..57f9d81a73 100644 --- a/tests/regressiontests/syndication/urls.py +++ b/tests/regressiontests/syndication/urls.py @@ -9,6 +9,7 @@ urlpatterns = patterns('django.contrib.syndication.views', (r'^syndication/complex/(?P.*)/$', feeds.ComplexFeed()), (r'^syndication/rss2/$', feeds.TestRss2Feed()), (r'^syndication/rss091/$', feeds.TestRss091Feed()), + (r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()), (r'^syndication/atom/$', feeds.TestAtomFeed()), (r'^syndication/custom/$', feeds.TestCustomFeed()), (r'^syndication/naive-dates/$', feeds.NaiveDatesFeed()),