Pregunta

Estoy tratando de convertir algunas de mis vistas de django de vistas basadas en funciones a vistas basadas en clases y me he encontrado con un pequeño problema.

Mi OO es algo débil y creo que el problema es que he perdido la noción de hacia dónde van las cosas.

Tengo un decorador de inicio de sesión personalizado que necesito en las vistas, así que tengo ...

Primero tengo la clase View de este ejemplo http://www.djangosnippets.org/snippets/760/

Entonces mi clase de vista se ve así ...

class TopSecretPage(View):
    @custom_login
    def __call__(self, request, **kwargs):
        #bla bla view stuff...
        pass

El problema es que mi decorador no puede acceder a request.session por alguna razón ...

Mi decorador se ve así ...

def myuser_login_required(f):
    def wrap(request, *args, **kwargs):

        # this check the session if userid key exist,
        # if not it will redirect to login page

        if 'field' not in request.session.keys():
        return wrap

¡Creo que es algo simple que me falta, así que gracias por su paciencia a todos!

ACTUALIZACIÓN: Ok, aquí está el error que recibo ...

" ViewDoesNotExist: Probé TopSecretPage en el módulo nombre del proyecto.application.views. El error fue: escriba el objeto 'TopSecretPage' no tiene atributo 'sesión' "

También simplifiqué el decorador para que se viera así ...

def myuser_login_required(request, *args, **kwargs):


    # this check the session if userid key exist,
    # if not it will redirect to login page

    if 'username' not in request.session.keys():
        return  HttpResponseRedirect(reverse("login-page"))

    return True
¿Fue útil?

Solución

El problema es que su contenedor espera " solicitud " como primer argumento, pero un método en una clase siempre toma "self" como el primer argumento Entonces, en su decorador, lo que cree que es el objeto de solicitud es en realidad TopSecretPage.

Las soluciones de Vinay o artran deberían funcionar, así que no las repetiré. Solo pensé que una descripción más clara del problema podría ser útil.

Otros consejos

La forma correcta de hacer esto para cualquier decorador aplicado a cualquier método de vista basado en clases es usar django.utils.decorators.method_decorator () . No estoy seguro de cuándo se introdujo method_decorator (), pero aquí hay un ejemplo / actualización en Django 1.2 notas de la versión . Úselo así:

from django.utils.decorators import method_decorator

class TopSecretPage(View):
    @method_decorator(custom_login)
    def __call__(self, request, **kwargs):
        #bla bla view stuff...
        pass

Este problema ha surgido antes . Se incluye una solución que podría funcionar para usted.

Actualización: Método de ejemplo con decorador:

class ContentView(View):

    # the thing in on_method() is the actual Django decorator
    #here are two examples
    @on_method(cache_page(60*5))
    @on_method(cache_control(max_age=60*5))
    def get(self, request, slug): # this is the decorated method
        pass #in here, you access request normally

En lugar de usar el decorador en la vista, puede decorar la url.

Por ejemplo en urls.py:

from my_decorators import myuser_login_required
from my_views import TopSecretPage

urlpatterns = patterns('', 
    (r'^whatever-the-url-is/

Puede que necesites jugar un poco con eso, pero es correcto.

, myuser_login_required(TopSecretPage), {}), )

Puede que necesites jugar un poco con eso, pero es correcto.

Esto es efectivamente un duplicado de Django - Forma correcta de pasar argumentos a los decoradores de CBV?  que describe la forma correcta de abordar esto. La forma correcta de hacer esto para django 1.9 es la siguiente:

@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
    ..
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top