From 2d352444b0354f163ac7d04fcddf84cc744a09d8 Mon Sep 17 00:00:00 2001 From: Russell Keith-Magee Date: Thu, 13 Jan 2011 14:51:34 +0000 Subject: [PATCH] Fixed #14176 -- Added forwards compatibility to the legacy syndication feed view. This allows class-based feeds to be deployed using the old-style feed view, as long as the feed requires no arguments (i.e., get_object returns None). Thanks to psychcf for the report, cwhaines for the investigation, and Andrew Godwin for the assist. git-svn-id: http://code.djangoproject.com/svn/django/trunk@15189 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/syndication/views.py | 13 ++++++++ docs/ref/contrib/comments/example.txt | 29 ++++++++++++---- .../comment_tests/tests/__init__.py | 1 + .../comment_tests/tests/feed_tests.py | 33 +++++++++++++++++++ tests/regressiontests/comment_tests/urls.py | 9 +++++ 5 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 tests/regressiontests/comment_tests/tests/feed_tests.py diff --git a/django/contrib/syndication/views.py b/django/contrib/syndication/views.py index ee692e2c0c2..9228e91687e 100644 --- a/django/contrib/syndication/views.py +++ b/django/contrib/syndication/views.py @@ -188,6 +188,7 @@ class Feed(object): def feed(request, url, feed_dict=None): """Provided for backwards compatibility.""" + from django.contrib.syndication.feeds import Feed as LegacyFeed import warnings warnings.warn('The syndication feed() view is deprecated. Please use the ' 'new class based view API.', @@ -206,6 +207,18 @@ def feed(request, url, feed_dict=None): except KeyError: raise Http404("Slug %r isn't registered." % slug) + # Backwards compatibility within the backwards compatibility; + # Feeds can be updated to be class-based, but still be deployed + # using the legacy feed view. This only works if the feed takes + # no arguments (i.e., get_object returns None). Refs #14176. + if not issubclass(f, LegacyFeed): + instance = f() + instance.feed_url = getattr(f, 'feed_url', None) or request.path + instance.title_template = f.title_template or ('feeds/%s_title.html' % slug) + instance.description_template = f.description_template or ('feeds/%s_description.html' % slug) + + return instance(request) + try: feedgen = f(slug, request).get_feed(param) except FeedDoesNotExist: diff --git a/docs/ref/contrib/comments/example.txt b/docs/ref/contrib/comments/example.txt index 424bdb13f5c..921fe03ffae 100644 --- a/docs/ref/contrib/comments/example.txt +++ b/docs/ref/contrib/comments/example.txt @@ -143,19 +143,36 @@ enable it in your project's ``urls.py``: from django.conf.urls.defaults import * from django.contrib.comments.feeds import LatestCommentFeed - feeds = { - 'latest': LatestCommentFeed, - } - urlpatterns = patterns('', # ... - (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed', - {'feed_dict': feeds}), + (r'^feeds/latest/$', LatestCommentFeed()), # ... ) Now you should have the latest comment feeds being served off ``/feeds/latest/``. +.. versionchanged:: 1.3 + +Prior to Django 1.3, the LatestCommentFeed was deployed using the +syndication feed view: + +.. code-block:: python + + from django.conf.urls.defaults import * + from django.contrib.comments.feeds import LatestCommentFeed + + feeds = { + 'latest': LatestCommentFeed, + } + + urlpatterns = patterns('', + # ... + (r'^feeds/(?P.*)/$', 'django.contrib.syndication.views.feed', + {'feed_dict': feeds}), + # ... + ) + + Moderation ========== diff --git a/tests/regressiontests/comment_tests/tests/__init__.py b/tests/regressiontests/comment_tests/tests/__init__.py index 449fea471dd..88c6f33203d 100644 --- a/tests/regressiontests/comment_tests/tests/__init__.py +++ b/tests/regressiontests/comment_tests/tests/__init__.py @@ -81,6 +81,7 @@ class CommentTestCase(TestCase): return d from regressiontests.comment_tests.tests.app_api_tests import * +from regressiontests.comment_tests.tests.feed_tests import * from regressiontests.comment_tests.tests.model_tests import * from regressiontests.comment_tests.tests.comment_form_tests import * from regressiontests.comment_tests.tests.templatetag_tests import * diff --git a/tests/regressiontests/comment_tests/tests/feed_tests.py b/tests/regressiontests/comment_tests/tests/feed_tests.py new file mode 100644 index 00000000000..0bc6618d9a8 --- /dev/null +++ b/tests/regressiontests/comment_tests/tests/feed_tests.py @@ -0,0 +1,33 @@ +import warnings + +from django.test.utils import get_warnings_state, restore_warnings_state + +from regressiontests.comment_tests.tests import CommentTestCase + + +class CommentFeedTests(CommentTestCase): + urls = 'regressiontests.comment_tests.urls' + feed_url = '/rss/comments/' + + def test_feed(self): + response = self.client.get(self.feed_url) + self.assertEquals(response.status_code, 200) + self.assertEquals(response['Content-Type'], 'application/rss+xml') + self.assertContains(response, '') + self.assertContains(response, 'example.com comments') + self.assertContains(response, 'http://example.com/') + self.assertContains(response, '') + + +class LegacyCommentFeedTests(CommentFeedTests): + feed_url = '/rss/legacy/comments/' + + def setUp(self): + self._warnings_state = get_warnings_state() + warnings.filterwarnings("ignore", category=DeprecationWarning, + module='django.contrib.syndication.views') + warnings.filterwarnings("ignore", category=DeprecationWarning, + module='django.contrib.syndication.feeds') + + def tearDown(self): + restore_warnings_state(self._warnings_state) diff --git a/tests/regressiontests/comment_tests/urls.py b/tests/regressiontests/comment_tests/urls.py index 0058689657b..052f7cf81d3 100644 --- a/tests/regressiontests/comment_tests/urls.py +++ b/tests/regressiontests/comment_tests/urls.py @@ -1,4 +1,9 @@ from django.conf.urls.defaults import * +from django.contrib.comments.feeds import LatestCommentFeed + +feeds = { + 'comments': LatestCommentFeed, +} urlpatterns = patterns('regressiontests.comment_tests.custom_comments.views', url(r'^post/$', 'custom_submit_comment'), @@ -7,3 +12,7 @@ urlpatterns = patterns('regressiontests.comment_tests.custom_comments.views', url(r'^approve/(\d+)/$', 'custom_approve_comment'), ) +urlpatterns += patterns('', + (r'^rss/legacy/(?P.*)/$', 'django.contrib.syndication.views.feed', {'feed_dict': feeds}), + (r'^rss/comments/$', LatestCommentFeed()), +)