Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 function 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?

like image 962
Nikolai Prokoschenko Avatar asked Sep 05 '11 09:09

Nikolai Prokoschenko


1 Answers

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
like image 153
Nikolai Prokoschenko Avatar answered Sep 22 '22 18:09

Nikolai Prokoschenko