Отладка принтами
Друг, если ты умеешь настраивать ротируемый лог в файл, знаешь все аналоги pdb, можешь перенаправить syslog в Kibana и знаешь, как хранятся данные в Elasticsearch, эта статья не для тебя. Посмотри лучше гифки с котиками.
Сегодня мы поговорим о том, чем все занимаются и редко говорят об этом: об отладке программ с помощью дебажных принтов. Это не самый крутой, но очень практичный и простой метод разобраться, что не так.
Вот есть код:
def get_context_data(self, **kwargs):
search_query = kwargs.get('search_query')
context = super().get_context_data(**kwargs)
context['qna_menu_item_active'] = True
if search_query:
models.QnaSearchQuery(
query=search_query,
user=self.request.user if self.request.user.is_authenticated() else None
).save()
context['object_list'] = context['object_list'].filter(
Q(title__icontains=search_query) |
Q(text_md__icontains=search_query) |
Q(category__icontains=search_query) |
Q(answers__text_md__icontains=search_query)
)
context['search_query'] = search_query
return context
Этот код должен правильно готовить данные для страницы вопросов и ответов, но он не работает. Можешь не пытаться разобраться в самом коде, он специально взят такой.
Итак, предположим, что тестов нет, автора нет, комментариев нет. Надо разобраться, в чём дело. Тесты, логирование, отладчик и специализированные библиотеки запрещено использовать из-за трудового договора.
В самом начале ещё можно не думать. Нужна переменная context
– давайте выведем её в консоль:
def get_context_data(self, **kwargs):
search_query = kwargs.get('search_query')
context = super().get_context_data(**kwargs)
context['qna_menu_item_active'] = True
if search_query:
models.QnaSearchQuery(
query=search_query,
user=self.request.user if self.request.user.is_authenticated() else None
).save()
context['object_list'] = context['object_list'].filter(
Q(title__icontains=search_query) |
Q(text_md__icontains=search_query) |
Q(category__icontains=search_query) |
Q(answers__text_md__icontains=search_query)
)
context['search_query'] = search_query
print(context)
return context
Теперь выполним код, посмотрим на результат в консоли.
Кажется, многое зависит от переменной search_query
: есть ли она в kwargs
, что в ней и во
что она превращается при конвертации в bool.
Смотрим:
def get_context_data(self, **kwargs):
print('search_query' in kwargs)
search_query = kwargs.get('search_query')
print(search_query)
print(bool(search_query))
context = super().get_context_data(**kwargs)
context['qna_menu_item_active'] = True
if search_query:
models.QnaSearchQuery(
query=search_query,
user=self.request.user if self.request.user.is_authenticated() else None
).save()
context['object_list'] = context['object_list'].filter(
Q(title__icontains=search_query) |
Q(text_md__icontains=search_query) |
Q(category__icontains=search_query) |
Q(answers__text_md__icontains=search_query)
)
context['search_query'] = search_query
print(context)
return context
Снова смотрим на данные в консоли.
Окей, с этим понятно. Теперь посмотрим, что у нас в context['object_list']
изначально и что мы туда кладём.
Чтобы не захламлять консоль, посмотрим на количество элементов в этом списке.
Сделаем отдельный запрос, чтобы его потом можно было легко удалить:
def get_context_data(self, **kwargs):
print('search_query' in kwargs)
search_query = kwargs.get('search_query')
print(search_query)
print(bool(search_query))
context = super().get_context_data(**kwargs)
context['qna_menu_item_active'] = True
if search_query:
models.QnaSearchQuery(
query=search_query,
user=self.request.user if self.request.user.is_authenticated() else None
).save()
context['object_list'] = context['object_list'].filter(
Q(title__icontains=search_query) |
Q(text_md__icontains=search_query) |
Q(category__icontains=search_query) |
Q(answers__text_md__icontains=search_query)
)
context['search_query'] = search_query
print(context)
return context
Снова запускаем. Данные в консоли навели на ошибку? Отлично, ради этого всё и задумывалось. Осталось удалить принты. Это просто, ведь основной код мы не трогали.
Данные в консоли не навели на ошибку? Значит, с теми переменными, на которые мы смотрели порядок.
Можно удалить неактуальные принты и таким же образом проверить другие переменные.
Вот, например, что-то с QnaSearchQuery
происходит.
Главное – не забыть поудалять отладочные принты перед коммитом. А то все узнают, что ты занимаешься ЭТИМ.
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.