2011-09-05 20 views
5

Estoy tratando de presentar vistas basadas en clases en mi proyecto. Se veía bien hasta ahora, hasta que encontré el siguiente problema.¿Cómo anulo `as_view` en vistas basadas en clases en Django?

Estoy usando django-navigation para crear migas de pan. Funciona así: una función de vista se decora y este decorador introduce un atributo en esa función llamada breadcrumb. En la plantilla, la URL actual o su parte se resuelven y la vista resultante se verifica para este atributo. Si está allí, se evalúa y el resultado es el texto de la ruta de navegación.

Dado que las vistas basadas en clases normalmente se representan mediante el método as_view(), parece que necesitaría decorarlo, sin embargo, dado que es un método de clase, no puedo acceder a la instancia allí, lo que depende de mi ruta de navegación en.

Adjuntando breadcrumb atributo a as_view() en el __init__() tampoco funcionó, o me salió mal la sintaxis. EDITAR: Por supuesto que no funcionó, ya que lo adjunté a as_view, no a su valor de retorno.

¿Alguna idea de cómo integrar correctamente el decorador breadcrumb y las vistas basadas en clases?

Respuesta

1

Creo que se puede hacer algo como esto en urls.py:

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

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

El método devuelve un as_view exigible, y que puede ser decorado. La sintaxis '@' es solo un atajo para lo que se hace en la línea 2.

+0

¿Se puede hacer esto en una sola línea? 'url (r '^ $', the_decorator (ListView.as_view()), name = 'app_index')'? –

+0

Sí, puedes :) – nfg

8

He resuelto esto ahora así. Puse mi rutina breadcrumb en un método en una clase secundaria y anulé as_view en mi vista base. También usó un truco del as_view real para obtener un puntero 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 
Cuestiones relacionadas