Domanda

Sto cercando di convertire alcune delle mie viste django da viste basate sulle funzioni a viste basate sulle classi e ho riscontrato un piccolo problema.

Il mio OO è un po 'debole e penso che il problema sia che ho perso le tracce di dove stanno andando le cose.

Ho un decoratore di login personalizzato di cui ho bisogno nelle viste, quindi ho ...

Per prima cosa ho la classe View da questo esempio http://www.djangosnippets.org/snippets/760/

Quindi la mia classe di visualizzazione è simile a questa ...

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

Il problema è che il mio decoratore non può accedere a request.session per qualche motivo ...

Il mio decoratore assomiglia a questo ...

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

Penso che sia qualcosa di semplice che mi manca, quindi grazie per la vostra pazienza a tutti!

UPDATE: Ok, quindi ecco l'errore che ottengo ...

" ViewDoesNotExist: provato TopSecretPage nel modulo projectname.application.views. Errore: l'oggetto tipo "TopSecretPage" non ha attributo "sessione" "

Ho anche semplificato il decoratore per assomigliare a questo ....

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
È stato utile?

Soluzione

Il problema è che il wrapper si aspetta " richiesta " come primo argomento, ma un metodo su una classe prende sempre " self " come primo argomento. Quindi nel tuo decoratore, ciò che pensa sia l'oggetto richiesta è in realtà TopSecretPage stesso.

Le soluzioni di Vinay o di artran dovrebbero funzionare, quindi non le ripeterò. Ho solo pensato che una descrizione più chiara del problema potesse essere utile.

Altri suggerimenti

Il modo corretto di eseguire questa operazione per qualsiasi decoratore applicato a qualsiasi metodo di visualizzazione basato su classi è utilizzare django.utils.decorators.method_decorator () . Non sono sicuro quando è stato introdotto method_decorator () ma ecco un esempio / aggiornamento in Django 1.2 note di rilascio . Usalo in questo modo:

from django.utils.decorators import method_decorator

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

Questo problema è emerso prima . È inclusa una soluzione che potrebbe funzionare per te.

Aggiornamento: metodo di esempio con decoratore:

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

Invece di usare il decoratore nella vista puoi decorare l'URL.

Ad esempio in urls.py:

from my_decorators import myuser_login_required
from my_views import TopSecretPage

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

Potrebbe essere necessario giocarci un po 'ma è giusto.

, myuser_login_required(TopSecretPage), {}), )

Potrebbe essere necessario giocarci un po 'ma è giusto.

Questo è effettivamente un duplicato di Django - Modo corretto di passare argomenti ai decoratori di CBV?  che descrive il modo corretto di affrontarlo. Il modo corretto di farlo per django 1.9 è il seguente:

@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
    ..
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top