Django – правильный способ передачи аргументов декораторам CBV?

В документации есть хорошие варианты применения декораторов. например, login_required для представлений на основе классов.

Однако я немного не понимаю, как передавать определенные аргументы вместе с декоратором, в этом случае я хотел бы изменить login_url декоратора.

Что-то вроде следующего, допустимо только:

@login_required(login_url="Accounts:account_login")
@user_passes_test(profile_check)
class AccountSelectView(TemplateView):
    template_name='select_account_type.html'

person Adam Starrh    schedule 27.11.2015    source источник
comment
Помимо изменения способа использования декоратора, вам необходимо изменить URL-адрес входа. Поскольку вы используете его в декораторе, используйте reverse_lazy, то есть login_url=reverse_lazy("Accounts:account_login").   -  person Alasdair    schedule 27.11.2015


Ответы (1)


Вы должны использовать @method_decorator с методами класса :

Метод класса — это не совсем то же самое, что отдельная функция, поэтому вы не можете просто применить декоратор функции к методу — вам нужно сначала преобразовать его в декоратор метода. Декоратор method_decorator преобразует декоратор функции в декоратор метода, чтобы его можно было использовать в методе экземпляра.

Затем просто вызовите декоратор с нужными вам аргументами и передайте его декоратору метода (вызвав функцию декоратора, которая может принимать аргументы, вы получите фактический декоратор на выходе). Не забудьте передать имя метода, который нужно декорировать, в качестве аргумента ключевого слова name (например, dispatch), если вы будете украшать класс вместо самого метода класса:

@method_decorator(login_required(login_url="Accounts:account_login"),
                  name='dispatch')
@method_decorator(user_passes_test(profile_check), name='dispatch')
class AccountSelectView(TemplateView):
    template_name='select_account_type.html'
person ndpu    schedule 27.11.2015
comment
Я импортирую from django.utils.decorators import method_decorator, но это решение выдает ошибку: "TypeError: method_decorator() got an unexpected keyword argument 'name' - person Adam Starrh; 28.11.2015
comment
Ах, мне просто нужно обновиться до Django 1.9! Большое спасибо. - person Adam Starrh; 28.11.2015
comment
Как это сделать на Django 1.8? - person alanjds; 11.08.2016
comment
@alanjds в 1.8 есть method_decorator, но в документах нет информации о возможности украшать сам класс... Попробуйте украсить метод в классе - person ndpu; 11.08.2016
comment
Скопировал из 1.9 в локальный модуль utils. Работал. Что мне понравилось в name, так это отсутствие необходимости переопределять внутренний метод. Спасибо, в любом случае. - person alanjds; 11.08.2016
comment
name принимает method name из CBV, к которому мы хотим применить декоратор. Я хотел бы применить его ко всему классу, который включает два метода get и put, но name принимает только один аргумент как string. Как это можно расширить дальше? и name='dispatch дает AnonymousUser - person neferpitou; 10.07.2020