浏览代码

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

Thanks julianb for the report and the initial patch, and Roman
Gladkov for working on tests.
Claude Paroz 12 年之前
父节点
当前提交
08d675a98f

+ 9 - 0
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
 

+ 8 - 0
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

+ 8 - 0
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.

+ 1 - 0
tests/regressiontests/syndication/urls.py

@@ -9,6 +9,7 @@ urlpatterns = patterns('django.contrib.syndication.views',
     (r'^syndication/complex/(?P<foo>.*)/$', 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()),