2012-08-26 33 views
5

Estoy escribiendo una vista que hereda de ListView y estoy tratando de restringir la vista a los usuarios que han iniciado sesión.¿Cuál es la diferencia entre los dos métodos de decoración de vistas basadas en clases?

https://docs.djangoproject.com/en/dev/topics/class-based-views/#decorating-in-urlconf dice que decorar con login_required en el URLconf "aplica el decorador por instancia. Si desea que se decore cada instancia de una vista, debe adoptar un enfoque diferente": ese enfoque es decorar el método de envío en el código de vista.

Pensé que sabía la diferencia entre una clase y una instancia, pero esta frase no significa nada para mí. ¿Alguien podría aclarar? Además de tener un decorador en el URLconf en lugar de en su definición de clase, ¿cuáles son las diferencias entre los dos enfoques?

El párrafo de arriba parece responder a la pregunta: "Como las vistas basadas en clases no son funciones, decorarlas funciona de manera diferente dependiendo de si está usando as_view o creando una subclase."

¿Realmente? Parece que puedo usar el enfoque URLconf con mi subclase de ListView.

Respuesta

5

Imagínese que tiene la siguiente visión basada en la clase:

class PostListView(ListView): 
    model = Post 

ProtectedPostListView = login_required(PostListView.as_view()) 

y su urls.py:

url(r'posts$', ProtectedPostListView) 

Si utiliza este enfoque entonces se pierde la capacidad de subclase ProtectedPostListView por ejemplo

class MyNewView(ProtectedPostListView): 
    #IMPOSSIBLE 

y esto es porque el .as_view() devuelve una función y después de aplicar el decorador login_required, se le deja una función, por lo que no es posible la creación de subclases.

Por otro lado, si utiliza el segundo método, es decir, use el decorador de métodos, la creación de subclases es posible. por ejemplo

class PostListView(ListView): 
    model = Post 

    @method_decorator(login_required) 
    def dispatch(self, *args, **kwargs): 
     return super(PostListView, self).dispatch(*args, **kwargs) 

class MyNewView(PostListView): 
    #LEGAL 
Cuestiones relacionadas