2009-09-15 4 views
3

Я пытаюсь преобразовать некоторые из своих представлений django из представлений, основанных на функции, в представления, основанные на классе, и я столкнулся с небольшой проблемой.django class view with decorator and sessions

Мое ОО слабое, и я думаю, проблема в том, что я потерял информацию о том, что происходит.

У меня есть пользовательский логин декоратор, что мне нужно от взглядов, так что я есть ...

Во-первых у меня есть вид класса из этого примера http://www.djangosnippets.org/snippets/760/

Тогда мой взгляд класс выглядит следующим образом .. .

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

проблема заключается в том, что мой декоратора не может получить доступ к request.session по какой-то причине ...

Мой декоратор выглядит так ...

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 

Я думаю, что это что-то простое, что мне не хватает, спасибо за ваше терпение всем!

UPDATE: Ok так вот ошибка, которую я получаю ...

"ViewDoesNotExist:. Пробовал TopSecretPage в модуле projectname.application.views Ошибка: тип объекта 'TopSecretPage' не имеет атрибута 'сессии'"

я упростил декоратора, а также посмотреть, как это ....

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

Я обновил свой ответ. –

ответ

2

Проблема заключается в том, что ваша оболочка ожидает «запрос» в качестве первого аргумента, но метод класса всегда принимает «я» в качестве первого аргумента. Таким образом, в вашем декораторе то, что он думает, является объектом запроса, фактически является самой TopSecretPage.

Решения Vinay или artran должны работать, поэтому я не буду их повторять. Просто подумал, что более ясное описание проблемы может оказаться полезным.

2

Эта проблема придумать before. Будет включено решение, которое может сработать для вас.

Update: Пример метода с декоратора:

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

Хм, хорошо, как я сказал, что мои умственные навыки слабы, и я действительно прочитал это, прежде чем публиковать этот вопрос. Я не вижу, как получить доступ к объекту запроса в функции декоратора из этого примера. –

+0

Спасибо за обновление! но у меня все еще есть проблема ха-ха. Я обновлю свой вопрос, чтобы попытаться показать его ... –

+0

Для Django 1.5 это '@method_decorator (cache_control (max_age = 86400)) def get (self, request, * args, ** kwargs):' – chrishiestand

1

Вместо того, чтобы использовать декоратор на представлении можно украсить URL.

Например, в 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), {}), 
) 

Вам может понадобиться, чтобы играть с этим немного, но это о праве.

+0

Я думаю, что это решение должно работать, но вам нужно создать экземпляр TopSecretPage: myuser_login_required (TopSecretPage()) –

6

Правильный способ сделать это для любого декоратора, применяемого к любому методу просмотра на основе классов, - использовать django.utils.decorators.method_decorator(). Я не уверен, когда был введен метод method_decorator(), но вот пример/обновление в Django 1.2 release notes.Используйте его так:

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

Можете ли вы привести это? Вы говорите, что представления на основе классов - это способ, которым django 1.2 говорит, чтобы делать представления? С тех пор я отказался от представлений, основанных на классе, по причинам обслуживания. –

+0

Обратите внимание на этот раздел примечаний к выпуску 1.2: –

+0

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

0

Это фактически дублирует Django - Correct way to pass arguments to CBV decorators? который описывает правильный способ решения этого вопроса. Правильный способ сделать это для django 1.9 выглядит следующим образом:

@method_decorator(myuser_login_required(), name='dispatch') 
class TopSecretPage(View): 
    .. 
Смежные вопросы