Представление класса Django с декоратором и сеансами
Вопрос
Я пытаюсь преобразовать некоторые из моих представлений django из представлений, основанных на функциях, в представления, основанные на классах, и столкнулся с небольшой проблемой.
Мой ОО довольно слаб, и я думаю, что проблема в том, что я потерял представление о том, что происходит.
У меня есть собственный декоратор входа в систему, который мне нужен в представлениях, поэтому у меня есть...
Сначала у меня есть класс View из этого примера.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
Я думаю, что мне не хватает чего-то простого, поэтому спасибо всем за терпение!
ОБНОВЛЯТЬ:Итак, вот ошибка, которую я получаю...
«Провидеснотексист:Попробовал TopSecretPage в модуле имя_проекта.приложение.представления.Ошибка была:объект типа «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
Решение
Проблема в том, что ваша оболочка ожидает «запрос» в качестве первого аргумента, но метод класса всегда принимает «я» в качестве первого аргумента.Итак, в вашем декораторе то, что он считает объектом запроса, на самом деле является самим TopSecretPage.
Решения Виная или Артрана должны сработать, поэтому я не буду их повторять.Просто подумал, что более четкое описание проблемы может быть полезно.
Другие советы
Правильный способ сделать это для любого декоратора, примененного к любому методу представления на основе классов, — использовать django.utils.decorators.method_decorator()
.Я не уверен, когда был представлен метод_decorator(), но вот пример/обновление в Django 1.2. примечания к выпуску.Используйте это следующим образом:
from django.utils.decorators import method_decorator
class TopSecretPage(View):
@method_decorator(custom_login)
def __call__(self, request, **kwargs):
#bla bla view stuff...
pass
Эта проблема возникла до.Включено решение, которое может вам подойти.
Обновлять: Пример метода с декоратором:
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
Вместо использования декоратора в представлении вы можете украсить 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), {}),
)
Возможно, вам придется немного с этим поиграть, но это правильно.
Фактически это дубликат Django – Правильный способ передачи аргументов декораторам CBV?который описывает правильный способ решения этой проблемы.Правильный способ сделать это для django 1.9 следующий:
@method_decorator(myuser_login_required(), name='dispatch')
class TopSecretPage(View):
..