vue de classe django avec décorateur et sessions
Question
J'essaie de convertir certaines de mes vues django de vues basées sur des fonctions en vues basées sur des classes et j'ai rencontré un petit problème.
Mon OO est un peu faible et je pense que le problème est que je ne sais plus trop où vont les choses.
J'ai un décorateur de connexion personnalisé dont j'ai besoin sur les vues pour que je puisse ...
J'ai d'abord la classe View de cet exemple http://www.djangosnippets.org/snippets/760/
Ensuite, ma classe de vue ressemble à ceci ...
class TopSecretPage(View):
@custom_login
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
Le problème est que mon décorateur ne peut pas accéder à request.session pour une raison quelconque ...
Mon décorateur ressemble à ceci ...
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
Je pense que c'est quelque chose de simple qui me manque alors merci pour votre patience à tous!
UPDATE: Ok, voici l'erreur que je reçois ...
& View; ViewDoesNotExist: Essayé TopSecretPage dans le module nomprojet.application.views. L'erreur était: l'objet type 'TopSecretPage' n'a pas d'attribut 'session' "
J'ai simplifié le décorateur aussi pour ressembler à ceci ....
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
La solution
Le problème est que votre wrapper attend la "requête". comme premier argument, mais une méthode sur une classe prend toujours "self" comme premier argument. Donc, dans votre décorateur, ce qu’il pense, c’est que l’objet requête est en réalité TopSecretPage lui-même.
Les solutions de Vinay ou d’Artran devraient fonctionner, donc je ne les répéterai pas. Je pensais qu'une description plus précise du problème pourrait être utile.
Autres conseils
Pour tout décorateur appliqué à une méthode de vue basée sur des classes, la bonne façon de procéder consiste à utiliser django.utils.decorators.method_decorator ()
. Je ne sais pas quand method_decorator () a été introduit, mais voici un exemple / update dans Django 1.2 notes de publication . Utilisez-le comme ceci:
from django.utils.decorators import method_decorator
class TopSecretPage(View):
@method_decorator(custom_login)
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
Ce problème a été relevé avant . Une solution est incluse qui pourrait fonctionner pour vous.
Mettre à jour: Exemple de méthode avec décorateur:
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
Au lieu d'utiliser le décorateur sur la vue, vous pouvez décorer l'URL.
Par exemple dans urls.py:
from my_decorators import myuser_login_required
from my_views import TopSecretPage
urlpatterns = patterns('',
(r'^whatever-the-url-is/
Vous aurez peut-être besoin de jouer avec cela un peu, mais c'est à peu près correct.
, myuser_login_required(TopSecretPage), {}),
)
Vous aurez peut-être besoin de jouer avec cela un peu, mais c'est à peu près correct.
Il s’agit en réalité d’un duplicata de Django - manière correcte de transmettre les arguments aux décorateurs CBV? qui décrit la bonne façon de résoudre ce problème. La bonne façon de procéder pour Django 1.9 est la suivante:
@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
..