开发者

How do I override `as_view` in class-based views in Django?

I'm trying to introduce class-based views in my project. Looked good so far, until I found the following problem.

I'm using django-navigation to create breadcrumbs. It works like this: a view functio开发者_运维问答n gets decorated and this decorator introduces an attribute on that function called breadcrumb. In the template, current URL or its part get resolved and the resulting view get checked for this attribute. If it's there, it's evaluated and the result is the breadcrumb text.

Since class-based views are normally represented by the as_view() method, it seems I would need to decorate it, however, since it's a class method, I can't really access the instance there, which my breadcrumb of course depends on.

Attaching breadcrumb attribute to as_view() in the __init__() didn't work either, or I got the syntax wrong. EDIT: Of course it didn't work, since I attached it to as_view, not to its return value.

Any ideas how to properly integrate that breadcrumb decorator and class-based views?


I've solved this now like this. I've put my breadcrumb routine in a method on a child class and overridden as_view in my base view. Also used a trick from the actual as_view to get a self pointer.

@classonlymethod
def as_view(cls, **initkwargs):
    self = cls(**initkwargs)
    view = super(MyBaseView, cls).as_view(**initkwargs)
    if hasattr(self, 'breadcrumb') and callable(getattr(self, 'breadcrumb', None)):
        return breadcrumb(self.breadcrumb)(view)
    return view


I guess you could do something like this in urls.py:

the_view = ListView.as_view(...)
the_view = the_decroator(the_view)

urlpatterns = patterns('',
    url(r'^$', the_view, name='app_index'),
    ...
)

The as_view method returns a callable, and that can be decorated. The '@'-syntax is just a shortcut for what is done on line 2.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜