vista de classe Django com o decorador e sessões
Pergunta
Eu estou tentando converter alguns dos meus pontos de vista Django ao longo de vista baseado em função para exibições de classe base e eu correr em um pequeno problema.
Meu OO é uma espécie de fraco e eu acho que o problema é que eu perdi o controle de onde as coisas estão indo.
Eu tenho um decorador de login personalizado que eu preciso sobre os pontos de vista, por isso tenho ...
Primeiro tenho a classe View a partir deste exemplo http://www.djangosnippets.org/snippets/760/
Então minha classe view parece com isso ...
class TopSecretPage(View):
@custom_login
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
O problema é que o meu decorador não pode acessar request.session por alguma razão ...
O meu decorador parece com isso ...
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
Eu acho que é algo simples que eu estou faltando por isso obrigado por sua paciência todos!
UPDATE: Ok então aqui está o erro que eu recebo ...
"ViewDoesNotExist: Tentei TopSecretPage em projectname.application.views módulo de erro foi:. Tipo de objeto 'TopSecretPage' tem nenhum atributo 'sessão'"
I simplificou o decorador, assim como para olhar como este ....
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
Solução
O problema é que seu wrapper espera "pedido" como o primeiro argumento, mas um método em uma classe sempre leva "eu" como o primeiro argumento. Assim, no seu decorador, que ele pensa que é o objeto do pedido é realmente TopSecretPage si.
As soluções da artran Ou Vinay ou deve funcionar, por isso não vou repeti-los. Só pensei que uma descrição mais clara do problema pode ser útil.
Outras dicas
A maneira correta de fazer isso para qualquer decorador aplicado a qualquer método de vista baseado em classes é usar django.utils.decorators.method_decorator()
. Eu não tenho certeza quando method_decorator () foi introduzido, mas aqui está um exemplo / atualização no Django 1.2 notas de lançamento . Usá-lo como este:
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 surgiu antes . A solução está incluído o que pode funcionar para você.
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
Em vez de usar o decorador na visão você pode decorar a url.
Por exemplo, em urls.py:
from my_decorators import myuser_login_required
from my_views import TopSecretPage
urlpatterns = patterns('',
(r'^whatever-the-url-is/$', myuser_login_required(TopSecretPage), {}),
)
Você pode precisar de brincar com isso um pouco, mas é sobre a direita.
Esta é efetivamente uma duplicata Django - Maneira correta de passar argumentos para decoradores CBV? que descreve a maneira correta de lidar com isso. A maneira correta de fazer isso para Django 1.9 é a seguinte:
@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
..