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.
精彩评论