2009-09-15 7 views
3

Je suis en train de convertir certaines de mes vues django à partir de vues fonctionnelles en vues basées sur les classes et j'ai rencontré un petit problème. Mon OO est un peu faible et je pense que le problème est que j'ai perdu la trace de l'endroit où vont les choses.Vue de classe django avec décorateur et sessions

J'ai un décorateur de connexion personnalisée que j'ai besoin sur les points de vue, donc j'ai ...

D'abord, j'ai la classe View de cet exemple http://www.djangosnippets.org/snippets/760/

Alors 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 qu'il est quelque chose de simple que je me manque donc merci pour votre patience tout le monde!

MISE À JOUR: Ok, donc voici l'erreur que je reçois ...

"ViewDoesNotExist. Essayé TopSecretPage dans projectname.application.views module erreur était: objet type 'TopSecretPage' n'a pas d'attribut 'session'"

J'ai simplifié le décorateur, ainsi 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 
+0

J'ai mis à jour ma réponse. –

Répondre

2

Le problème est que votre wrapper attend "request" 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 est que l'objet de requête est en fait TopSecretPage lui-même.

Les solutions de Vinay ou d'artran devraient fonctionner, donc je ne les répéterai pas. Je pensais juste qu'une description plus claire du problème pourrait être utile.

2

ce problème est venu before. Une solution est incluse qui pourrait fonctionner pour vous.

Mise à jour: méthode Exemple 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 
+0

Hmm, bien comme je l'ai dit, mes compétences oop sont faibles et je l'ai lu avant de poster cette question. Je ne vois pas comment accéder à l'objet request dans la fonction décorator à partir de cet exemple. –

+0

Merci pour la mise à jour! mais j'ai toujours le problème haha. Je vais mettre à jour ma question pour essayer de le montrer ... –

+0

Django 1.5, il est '@method_decorator (cache_control (max_age = 86400)) obtenir def (auto, demande, * args, ** kwargs):' – chrishiestand

1

Au lieu d'utiliser le décorateur sur la vue que 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/$', myuser_login_required(TopSecretPage), {}), 
) 

Vous devrez peut-être jouer avec cela un peu, mais il est à peu près juste.

+0

Je pense que cette solution devrait fonctionner, mais vous devez instancier TopSecretPage: myuser_login_required (TopSecretPage()) –

6

La méthode correcte pour ce faire pour n'importe quel décorateur appliqué à n'importe quelle méthode de vue basée sur la classe est d'utiliser django.utils.decorators.method_decorator(). Je ne suis pas sûr quand method_decorator() a été introduit mais voici un exemple/update dans le Django 1.2 release notes.Utilisez 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 
+0

Pouvez-vous citer cela? Êtes-vous en train de dire que les vues basées sur les classes sont la façon dont django 1.2 dit faire des vues? Depuis, je me suis éloigné des vues basées sur les classes pour des raisons de maintenance. –

+0

Jetez un oeil à cette section des notes de version 1.2: –

+0

https://docs.djangoproject.com/fr/1.3/releases/1.2/#user-passes-test-login-required-and-permission-required –

0

Ceci est en fait un double de Django - Correct way to pass arguments to CBV decorators? qui décrit la manière correcte d'aborder ce sujet. La manière correcte de le faire pour django 1.9 est la suivante:

@method_decorator(myuser_login_required(), name='dispatch') 
class TopSecretPage(View): 
    ..