Как добавить/изменить атрибут в представлении на основе класса Django из декоратора?

У меня есть представление Django на основе классов следующим образом:

class myView(TemplateView):
    template_name = 'templateFile.html'
    request = None

    @method_decorator(request_management)
    def dispatch(self, request, *args, **kwargs):
        ...
        return super(myView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, *args, **kwargs):
        ctx = super(newFeatures, self).get_context_data(**kwargs)
        ctx['requester'] = self.requester
        return ctx

В моем декораторе request_management я хотел бы установить значение myView.request в аргумент, который был передан в функцию отправки. Итак, я делаю что-то вроде этого:

def request_management(function):
    @wraps(function)
    def decorator(*args, **kwargs):
        logger.debug("request = %s" % str(args[0]))
        # I want to say here something like: 
        # self.request = args[0]
        # but of course, "self" is not defined in this context.
        return function(*args, **kwargs)
    return decorator

Но из декоратора я не могу получить доступ к экземпляру «я» декорированного метода. Как я могу получить этот экземпляр и прикрепить к нему атрибут с именем request, чтобы я мог использовать этот атрибут в других методах этого экземпляра?


person Saqib Ali    schedule 07.04.2014    source источник
comment
Я ответил ниже, но знаете ли вы, что self.request уже создан для вас в представлениях на основе классов? См. здесь.   -  person Kevin Christopher Henry    schedule 07.04.2014
comment
Нет. Я понятия не имел. Спасибо! Но есть и другие параметры, которые мне нужно добавить к себе в качестве атрибутов.   -  person Saqib Ali    schedule 07.04.2014
comment
Я почти уверен, что ты делаешь это неправильно. По моему опыту, переопределение dispatch почти никогда не бывает правильной стратегией. Кроме того, при работе с представлениями на основе классов обычно рекомендуется рассмотреть возможность использования миксина. Чего именно вы пытаетесь достичь?   -  person Berislav Lopac    schedule 08.04.2014


Ответы (1)


Целью method_decorator является преобразование декоратора функции в декоратор метода. Но так как вы пишете свой собственный декоратор, вы можете просто написать его как настоящий декоратор метода:

class myView(TemplateView):

    @request_management
    def dispatch(self, request, *args, **kwargs):
        ... 
        return super(myView, self).dispatch(request, *args, **kwargs)

    def request_management(method): 
        @wraps(method)
        def decorator(self, request, *args, **kwargs):
            logger.debug("request = %s" % str(request))
            self.request = request

            return method(self, request, *args, **kwargs)

        return decorator
person Kevin Christopher Henry    schedule 07.04.2014