How to cache the output of Django 1.2 RSS class based views?

240 views
Skip to first unread message

Brian Neal

unread,
Mar 7, 2010, 11:48:26 PM3/7/10
to Django users
Before the Django 1.2 beta and the class-based Feed views, I was doing
this to cache my RSS feeds:

urls.py:
from django.contrib.syndication.views import feed as syndication_feed
from django.views.decorators.cache import cache_page

urlpatterns = patterns('',
url(r'^feeds/(?P<url>.*)/$',
cache_page(syndication_feed, 60 * 15),
{'feed_dict': feeds},
'feeds-news'),

Is there a way to do something similar to this now with the 1.2 Feed
classes? This doesn't seem to work when the argument to cache_page is
now an instance of a Feed object (I get an AttributeError; my feed
class has no attribute '__name__'):

url(r'^feeds/news/$',
cache_page(LatestNewsFeed(), 60 * 15),
name='feeds-news'),

Or am I going about this wrong and I need to put the cache_page
decorator on an overridden __call__ method on my derived Feed class
(which simply calls the base class)?

Thanks,
BN

Brian Neal

unread,
Mar 11, 2010, 9:01:03 AM3/11/10
to Django users
On Mar 7, 10:48 pm, Brian Neal <bgn...@gmail.com> wrote:
> Before the Django 1.2 beta and the class-based Feed views, I was doing
> this to cache my RSS feeds:
>
> urls.py:
> from django.contrib.syndication.views import feed as syndication_feed
> from django.views.decorators.cache import cache_page
>
> urlpatterns = patterns('',
>    url(r'^feeds/(?P<url>.*)/$',
>       cache_page(syndication_feed, 60 * 15),
>       {'feed_dict': feeds},
>       'feeds-news'),
>
> Is there a way to do something similar to this now with the 1.2 Feed
> classes? This doesn't seem to work when the argument to cache_page is
> now an instance of a Feed object (I get an AttributeError; my feed
> class has no attribute '__name__'):
>
>    url(r'^feeds/news/$',
>        cache_page(LatestNewsFeed(), 60 * 15),
>        name='feeds-news'),
>

Well, I'm not sure if it was the intent to break this use case. Any
thoughts?

But I found a work around after talking to Rob Hudson. You can
override the syndication base class __call__ function and decorate
that. But another new thing here is you have to use the new
method_decorator [1]:

class MyFeed(Feed):

@method_decorator(cache_page(60 * 60))
def __call__(self, request, *args, **kwargs):
return super(MyFeed, self).__call__(request, *args, **kwargs)

Again, I'm not sure if this was supposed to break like this, as there
are certain advantages to do this in the URLconf, as noted in the docs
for cache_page.

BN

[1] http://docs.djangoproject.com/en/dev/releases/1.2/#user-passes-test-login-required-and-permission-required

Russell Keith-Magee

unread,
Mar 11, 2010, 8:46:15 PM3/11/10
to django...@googlegroups.com
On Thu, Mar 11, 2010 at 10:01 PM, Brian Neal <bgn...@gmail.com> wrote:
> On Mar 7, 10:48 pm, Brian Neal <bgn...@gmail.com> wrote:
>> Before the Django 1.2 beta and the class-based Feed views, I was doing
>> this to cache my RSS feeds:
>>
>> urls.py:
>> from django.contrib.syndication.views import feed as syndication_feed
>> from django.views.decorators.cache import cache_page
>>
>> urlpatterns = patterns('',
>>    url(r'^feeds/(?P<url>.*)/$',
>>       cache_page(syndication_feed, 60 * 15),
>>       {'feed_dict': feeds},
>>       'feeds-news'),
>>
>> Is there a way to do something similar to this now with the 1.2 Feed
>> classes? This doesn't seem to work when the argument to cache_page is
>> now an instance of a Feed object (I get an AttributeError; my feed
>> class has no attribute '__name__'):
>>
>>    url(r'^feeds/news/$',
>>        cache_page(LatestNewsFeed(), 60 * 15),
>>        name='feeds-news'),
>>
>
> Well, I'm not sure if it was the intent to break this use case. Any
> thoughts?

Apologies for not replying earlier, Brian.

We didn't specifically aim to break this use case. I can't think of
any conceptual reason that you shouldn't be able to cache class-based
feeds; this looks to be entirely a technical problem caused by the
fact that cache_page doesn't work nicely with callable classes.

One quick workaround that seems to work in my testing is to add
exactly what is being asked for -- the cache_page decorator needs a
__name__ attribute... so provide one. Add a __name__ class attribute
to the feed class::

class LatestNewsFeed(Feed):
__name__ = 'LatestNewsFeed'

A better solution is for us to fix the cache_page decorator so that it
will look at __class__.__name__ (or some similar attribute) if
__name__ isn't available. I've added ticket #13093 to track this
problem, and I'll make sure it's addressed before 1.2 is released.

Yours,
Russ Magee %-)

Reply all
Reply to author
Forward
0 new messages