Django – Как войти в декоратор?

Я хочу настроить ведение журнала для каждой отдельной функции API, используя для простоты decorator. Но продолжайте сталкиваться с той же ошибкой. Пожалуйста помоги

settings.py

log_dir = './log'                                          #create a folder for logging
log_dir = os.path.abspath(log_dir)
    if log_dir and not os.path.exists(log_dir):
        os.mkdir(log_dir)

LOGGING = {
        'version': 1,
        'disable_existing_loggers': True,
        'formatters': {
            'short': {                                                          #for internal errors
                'format': '%(asctime)s.%(msecs)03d|%(levelname)s|%(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S',                  
            },
            'data': {                                                      #for error relate to db
                'format': '%(asctime)s.%(msecs)03d|%(message)s',
                'datefmt': '%Y-%m-%d %H:%M:%S',
            },
        },
        'handlers': {
            'file_fatal': {                                           #folder for db errors
                'level': 'CRITICAL',
                'class': 'logging.FileHandler',
                'filename': os.path.join(log_dir, 'fatal.log').replace('\\', '/'),
                'formatter': 'data',
            },
            'file_info': {                                             #folder for internal errors
                'level': 'DEBUG',                                                 
                'class': 'logging.FileHandler',
                'filename': os.path.join(log_dir, 'info.log').replace('\\', '/'),
                'formatter': 'short',
            },
        },
        'loggers': {
            'main': {
                'handlers': ['file_info'],
                'level': 'DEBUG',
                'propagate': True,
            },
        }
    }

Это мой views.py

Проверьте, работает ли функция или нет

def func_detail(func):                            #function for the decorator
    @wraps(func)
    def func_wrapper(requests,*args, **kwargs):
        log = logging.getLogger('main')
        try: 
            response = func(requests, *args, **kwargs)
            return response
        except:
            log.debug('Exception', func.__name__)

Ниже мой API

class simple_function(generics.GenericAPIView):
    @func_detail
    def get(self,requests):
        input_1 = requests.GET.get('input_1')
        input_2 = requests.GET.get('input_2')
        input_3 = requests.GET.get('input_3')
        return JsonResponse([{'aaa':111, 'bbb':222, 'ccc':333}],safe =False)

Получил эту ошибку при запуске:

TypeError в объекте /simple_function 'NoneType' не может быть вызван

Когда я comment выхожу из декоратора @func_detail, он работает нормально

Вы пытались вернуть функцию func_wrapper? После установки переменной ответа в функции func_wrapper верните ее.

retro_coder 20.12.2020 17:33

Это тоже не работает

Chau Loi 20.12.2020 17:37

О, как насчет удаления параметра «запросы» в функции-оболочке, поскольку он уже получен через аргументы? Или попробуйте решение @schwobaseggl ниже?

retro_coder 20.12.2020 17:42

@guten_pro спасибо за поддержку, однако удаление requests не работает

Chau Loi 20.12.2020 17:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python.
Некоторые методы, о которых вы не знали, что они существуют в Python.
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
320
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша украшенная функция должна либо вернуть ответ, либо вызвать исключение. При этом ваш декоратор должен возвращать функцию.

def func_detail(func):
    @wraps(func)
    def func_wrapper(request, *args, **kwargs):
        try: 
            response = func(request, *args, **kwargs)
            return response
        except:
            log = logging.getLogger('main')
            log.debug('Exception', func.__name__)
            raise  # reraise, otherwise your view returns None
    
    return func_wrapper  # decorator must return the new function

Красиво работает, спс

Chau Loi 20.12.2020 17:52

Другие вопросы по теме