Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

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

Thanks julianb for the report and the initial patch, and Roman
Gladkov for working on tests.
  • Loading branch information...
commit 08d675a98f1ae1d27f7e1946125ed5316c576802 1 parent d0345b7
Claude Paroz authored September 30, 2012
9  django/contrib/syndication/views.py
... ...
@@ -1,5 +1,7 @@
1 1
 from __future__ import unicode_literals
2 2
 
  3
+from calendar import timegm
  4
+
3 5
 from django.conf import settings
4 6
 from django.contrib.sites.models import get_current_site
5 7
 from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
@@ -8,6 +10,7 @@
8 10
 from django.utils import feedgenerator, tzinfo
9 11
 from django.utils.encoding import force_text, iri_to_uri, smart_text
10 12
 from django.utils.html import escape
  13
+from django.utils.http import http_date
11 14
 from django.utils.timezone import is_naive
12 15
 
13 16
 
@@ -22,6 +25,7 @@ def add_domain(domain, url, secure=False):
22 25
         url = iri_to_uri('%s://%s%s' % (protocol, domain, url))
23 26
     return url
24 27
 
  28
+
25 29
 class FeedDoesNotExist(ObjectDoesNotExist):
26 30
     pass
27 31
 
@@ -38,6 +42,11 @@ def __call__(self, request, *args, **kwargs):
38 42
             raise Http404('Feed object does not exist.')
39 43
         feedgen = self.get_feed(obj, request)
40 44
         response = HttpResponse(content_type=feedgen.mime_type)
  45
+        if hasattr(self, 'item_pubdate'):
  46
+            # if item_pubdate is defined for the feed, set header so as
  47
+            # ConditionalGetMiddleware is able to send 304 NOT MODIFIED
  48
+            response['Last-Modified'] = http_date(
  49
+                timegm(feedgen.latest_post_date().utctimetuple()))
41 50
         feedgen.write(response, 'utf-8')
42 51
         return response
43 52
 
8  tests/regressiontests/syndication/feeds.py
@@ -46,6 +46,14 @@ class TestRss091Feed(TestRss2Feed):
46 46
     feed_type = feedgenerator.RssUserland091Feed
47 47
 
48 48
 
  49
+class TestNoPubdateFeed(views.Feed):
  50
+    title = 'Test feed'
  51
+    link = '/feed/'
  52
+
  53
+    def items(self):
  54
+        return Entry.objects.all()
  55
+
  56
+
49 57
 class TestAtomFeed(TestRss2Feed):
50 58
     feed_type = feedgenerator.Atom1Feed
51 59
     subtitle = TestRss2Feed.description
8  tests/regressiontests/syndication/tests.py
@@ -226,6 +226,14 @@ def test_aware_datetime_conversion(self):
226 226
         updated = doc.getElementsByTagName('updated')[0].firstChild.wholeText
227 227
         self.assertEqual(updated[-6:], '+00:42')
228 228
 
  229
+    def test_feed_last_modified_time(self):
  230
+        response = self.client.get('/syndication/naive-dates/')
  231
+        self.assertEqual(response['Last-Modified'], 'Thu, 03 Jan 2008 19:30:00 GMT')
  232
+
  233
+        # No last-modified when feed has no item_pubdate
  234
+        response = self.client.get('/syndication/no_pubdate/')
  235
+        self.assertFalse(response.has_header('Last-Modified'))
  236
+
229 237
     def test_feed_url(self):
230 238
         """
231 239
         Test that the feed_url can be overridden.
1  tests/regressiontests/syndication/urls.py
@@ -9,6 +9,7 @@
9 9
     (r'^syndication/complex/(?P<foo>.*)/$', feeds.ComplexFeed()),
10 10
     (r'^syndication/rss2/$', feeds.TestRss2Feed()),
11 11
     (r'^syndication/rss091/$', feeds.TestRss091Feed()),
  12
+    (r'^syndication/no_pubdate/$', feeds.TestNoPubdateFeed()),
12 13
     (r'^syndication/atom/$', feeds.TestAtomFeed()),
13 14
     (r'^syndication/custom/$', feeds.TestCustomFeed()),
14 15
     (r'^syndication/naive-dates/$', feeds.NaiveDatesFeed()),

0 notes on commit 08d675a

Please sign in to comment.
Something went wrong with that request. Please try again.