2011-09-05 7 views
5

Próbuję wprowadzić widoki oparte na klasach w moim projekcie. Wyglądało dobrze do tej pory, dopóki nie znalazłem następujący problem.Jak przesłonić "as_view" w widokach opartych na klasach w Django?

Używam django-navigation do tworzenia bułek tartych. Działa to tak: funkcja widoku zostaje ozdobiona, a ten dekorator wprowadza atrybut do tej funkcji o nazwie breadcrumb. W szablonie rozwiązuje się bieżący adres URL lub jego część, a wynikowy widok jest sprawdzany pod kątem tego atrybutu. Jeśli tam jest, jest oceniany, a wynikiem jest tekst nawigacyjny.

Ponieważ widoki oparte na klasach są zwykle reprezentowane przez metodę as_view(), wydaje się, że muszę ją udekorować, jednak ponieważ jest to metoda klasy, nie mogę uzyskać dostępu do instancji, która oczywiście zależy na.

Dołączanie atrybutu breadcrumb do as_view() w __init__() również nie działa, lub mam błędną składnię. EDIT: Oczywiście to nie zadziałało, ponieważ podłączyłem go do as_view, a nie do jego wartości zwracanej.

Jakieś pomysły na poprawną integrację tego dekoratora breadcrumb i widoków opartych na klasach?

Odpowiedz

1

Myślę, że można zrobić coś takiego w urls.py:

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

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

Sposób as_view zwraca wpłacone, a które mogą być urządzone. Składnia '@' jest po prostu skrótem do tego, co robi się w linii 2.

+0

Czy możesz to zrobić w pojedynczej linii? 'url (r '^ $', the_decorator (ListView.as_view()), name = 'app_index')'? –

+0

Tak, możesz :) – nfg

8

Rozwiązałem to teraz w ten sposób. W moim widoku podstawowym umieściłem moją procedurę breadcrumb w klasie potomnej i zastąpię ją as_view. Zastosowano również sztuczkę z rzeczywistego as_view, aby uzyskać wskaźnik self.

@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