it-swarm.com.ru

Как отлаживать в Django, хороший способ?

Итак, я начал учиться кодировать в Python и позже Django . В первый раз было трудно смотреть на трассировки и на самом деле выяснить, что я сделал неправильно и где была синтаксическая ошибка. Прошло немного времени, и некоторое время спустя, я думаю, у меня появилась процедура отладки моего кода Django. Так как это было сделано на ранних этапах моего опыта программирования, я сел и подумал, что, как я это делал, было неэффективно и могло бы быть сделано быстрее. Мне обычно удается находить и исправлять ошибки в моем коде, но мне интересно, стоит ли мне делать это быстрее?

Я обычно просто использую отладочную информацию, которую Django дает, когда она включена. Когда все заканчивается так, как я думал, я сильно нарушаю поток кода из-за синтаксической ошибки и смотрю на переменные в этой точке потока, чтобы выяснить, где код делает что-то отличное от того, что я хотел.

Но можно ли это улучшить? Есть ли хорошие инструменты или лучшие способы отладки вашего кода Django?

517
googletorp

Есть множество способов сделать это, но самый простой - просто Использовать отладчик Python . Просто добавьте следующую строку в функцию просмотра Django:

import pdb; pdb.set_trace()

Если вы попытаетесь загрузить эту страницу в своем браузере, браузер зависнет, и вы получите запрос на продолжение отладки при реальном выполнении кода.

Однако есть и другие варианты (я их не рекомендую):

* return HttpResponse({variable to inspect})

* print {variable to inspect}

* raise Exception({variable to inspect})

Но отладчик Python (pdb) настоятельно рекомендуется для всех типов кода Python. Если вы уже пользуетесь pdb, вам также следует взглянуть на IPDB , который использует ipython для отладки.

Еще одно полезное расширение для pdb

pdb ++ , предложено Antash .

pudb , предложено PatDuJour .

Использование отладчика Python в Django , предложено Seafangs .

482
simplyharsh

Мне очень нравится интерактивный отладчик Werkzeug . Это похоже на страницу отладки Django, за исключением того, что вы получаете интерактивную оболочку на каждом уровне трассировки. Если вы используете Django-extensions , вы получите команду управления runserver_plus, которая запускает сервер разработки и дает вам отладчик Werkzeug для исключений.

Конечно, вы должны запускать это только локально, поскольку это дает любому пользователю с браузером права на выполнение произвольного кода Python в контексте сервера.

219
Benjamin Wohlwend

Небольшая подсказка для тегов шаблонов:

@register.filter 
def pdb(element):
    import pdb; pdb.set_trace()
    return element

Теперь внутри шаблона вы можете выполнить {{ template_var|pdb }} и войти в сеанс pdb (если вы работаете на локальном сервере devel), где вы можете проверить element до глубины души.

Это очень хороший способ увидеть, что случилось с вашим объектом, когда он прибывает в шаблон. 

155
Koobz

Есть несколько инструментов, которые хорошо взаимодействуют и могут облегчить вашу задачу отладки.

Наиболее важной является панель отладки Django .

Тогда вам нужна хорошая регистрация с помощью Python logging средства. Вы можете отправить вывод журнала в файл журнала, но более простым вариантом является отправка вывода журнала в firepython . Для этого вам нужно использовать браузер Firefox с расширением firebug . Firepython включает в себя плагин Firebug, который будет отображать любые журналы на стороне сервера на вкладке Firebug.

Сам Firebug также важен для отладки Javascript стороны любого приложения, которое вы разрабатываете. (Конечно, если у вас есть JS-код).

Мне также понравился Django-viewtools для интерактивной отладки представлений с использованием pdb, но я не так часто его использую.

Существуют и другие полезные инструменты, такие как бульдозер, для отслеживания утечек памяти (в ответах на SO приведены и другие полезные советы по отслеживанию памяти).

80
Van Gale

Я использую PyCharm (тот же движок Pydev, что и Eclipse). Действительно помогает мне визуально пройтись по моему коду и посмотреть, что происходит.

54
PhoebeB

До сих пор почти все было упомянуто, поэтому я только добавлю, что вместо pdb.set_trace() можно использовать ipdb.set_trace () , который использует iPython и, следовательно, более мощный (автозаполнение и другие полезности). Для этого требуется пакет ipdb, поэтому вам нужно только pip install ipdb

41
Tomasz Zielinski

Я вставил Django-pdb в PyPI . Это простое приложение, которое означает, что вам не нужно редактировать исходный код каждый раз, когда вы хотите взломать pdb.

Установка просто ...

  1. pip install Django-pdb
  2. Добавьте 'Django_pdb' к своему INSTALLED_APPS

Теперь вы можете запустить: manage.py runserver --pdb для разбиения на pdb в начале каждого просмотра ...

bash: manage.py runserver --pdb
Validating models...

0 errors found
Django version 1.3, using settings 'testproject.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

GET /
function "myview" in testapp/views.py:6
args: ()
kwargs: {}

> /Users/tom/github/Django-pdb/testproject/testapp/views.py(7)myview()
-> a = 1
(Pdb)

И запустите: manage.py test --pdb, чтобы разбить pdb на тестовые сбои/ошибки ...

bash: manage.py test testapp --pdb
Creating test database for alias 'default'...
E
======================================================================
>>> test_error (testapp.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File ".../Django-pdb/testproject/testapp/tests.py", line 16, in test_error
    one_plus_one = four
NameError: global name 'four' is not defined
======================================================================

> /Users/tom/github/Django-pdb/testproject/testapp/tests.py(16)test_error()
-> one_plus_one = four
(Pdb)

Проект размещен на GitHub , материалы приветствуются, конечно.

32
Tom Christie

Самый простой способ отладки Python - особенно для программистов, которые привыкли к Visual Studio - это использование PTVS (Python Tools for Visual Studio). Шаги просты: 

  1. Загрузите и установите его с http://pytools.codeplex.com/
  2. Установите точки останова и нажмите F5. 
  3. Ваша точка останова достигнута, вы можете просматривать/изменять переменные так же просто, как отлаживать программы на C #/C++. 
  4. Это все :) 

Если вы хотите отладить Django с помощью PTVS, вам нужно сделать следующее: 

  1. В настройках проекта - вкладка «Общие» установите «Startup File» на «manage.py», точку входа в программу Django. 
  2. В настройках проекта - вкладка «Отладка» установите «Аргументы скрипта» на «runserver --noreload». Ключевым моментом здесь является «--noreload». Если вы не установите его, ваши контрольные точки не будут достигнуты. 
  3. Наслаждайся этим.
20
029xue

Я использую pyDev с Eclipse действительно хорошо, устанавливаю точки останова, шагаю в код, просматриваю значения любых объектов и переменных, пробую это.

15
gath

Я использую PyCharm и поддерживаю его до конца. Это стоило мне немного, но я должен сказать, что преимущество, которое я получаю от этого, бесценно. Я попробовал отладку с консоли, и я очень благодарен людям, которые могут это сделать, но для меня возможность визуальной отладки моих приложений - это здорово.

Я должен сказать, однако, PyCharm действительно занимает много памяти. Но опять же, ничего хорошего в жизни не бывает свободным. Они только что вышли с последней версией 3. Она также очень хорошо работает с Django, Flask и Google AppEngine. В общем, я бы сказал, что это отличный удобный инструмент для любого разработчика.

Если вы еще не используете его, я бы порекомендовал получить пробную версию на 30 дней, чтобы взглянуть на возможности PyCharm. Я уверен, что есть и другие инструменты, такие как Aptana. Но я думаю, мне просто нравится, как выглядит PyCharm. Я чувствую себя очень комфортно, отлаживая свои приложения там.

10
Khan

С моей точки зрения, мы могли бы разбить общие задачи отладка кода на три различных шаблона использования:

  1. Кое-что вызвало исключение: runserver_plus 'Werkzeug отладчик на помощь. Возможность запуска пользовательского кода на всех уровнях трассировки является убийцей. И если вы полностью застряли, вы можете создать Gist, чтобы поделиться с одним щелчком мыши.
  2. Страница отображается, но результат неверен: снова Werkzeug качается. Чтобы создать точку останова в коде, просто введите assert False в том месте, где вы хотите остановиться.
  3. Код работает неправильно, но быстрый просмотр не помогает. Скорее всего, алгоритмическая проблема. Вздох. Затем я обычно запускаю консольный отладчик PuDB : import pudb; pudb.set_trace(). Основное преимущество перед [i] pdb заключается в том, что PuDB (несмотря на то, что вы выглядите как 80-е годы) делает настройку пользовательских выражений часов на одном дыхании. И отладка группы вложенных циклов намного проще с графическим интерфейсом.

Ах, да, горе шаблонов. Наиболее распространенная (для меня и моих коллег) проблема - это неправильный контекст: либо у вас нет переменной, либо у вашей переменной нет какого-либо атрибута. Если вы используете панель инструментов отладки , просто проверьте контекст в разделе «Шаблоны» или, если этого недостаточно, установите разрыв в коде ваших представлений сразу после того, как ваш контекст заполнен.

Такие вот дела.

9
Alex Morozov

Иногда, когда я хочу изучить конкретный метод и вызывать pdb просто слишком громоздко, я бы добавил:

import IPython; IPython.embed()

IPython.embed() запускает оболочку IPython, которая имеет доступ к локальным переменным с того места, где вы ее вызываете. 

8
Lie Ryan

Я только что нашел wdb ( http://www.rkblog.rk.edu.pl/w/p/debugging-python-code-browser-wdb-debugger/?goback=%2Egde_25827_member_255996401 ). Он имеет довольно приятный пользовательский интерфейс/GUI со всеми прибамбасами. Автор говорит это о WDB -

«Существуют IDE, такие как PyCharm, которые имеют свои собственные отладчики. Они предлагают схожий или равный набор функций ... Однако, чтобы использовать их, вы должны использовать эти конкретные IDE (а некоторые из них не являются бесплатными или могут быть доступны не для всех платформы). Выберите правильный инструмент для ваших нужд. "

Думаю, я просто передам это.

Также очень полезная статья о отладчиках Python:https://zapier.com/engineering/debugging-python-boss/

Наконец, если вы хотите увидеть отличную графическую распечатку вашего стека вызовов в Django, проверьте: https://github.com/joerick/pyinstrument . Просто добавьте pyinstrument.middleware.ProfilerMiddleware в MIDDLEWARE_CLASSES, затем добавьте? Profile в конец URL-адреса запроса, чтобы активировать профилировщик. 

Можно также запустить pyinstrument из командной строки или путем импорта в качестве модуля.

6
Hutch

Я настоятельно рекомендую epdb (Extended Python Debugger). 

https://bitbucket.org/dugan/epdb

Одна вещь, которая мне нравится в epdb для отладки Django или других веб-серверов Python, это команда epdb.serve (). Это устанавливает трассировку и передает ее на локальный порт, к которому вы можете подключиться. Типичный вариант использования:

У меня есть мнение, что я хочу пройти через шаг за шагом. Я вставлю следующее в тот момент, когда я хочу установить трассировку.

import epdb; epdb.serve()

Как только этот код выполняется, я открываю интерпретатор Python и подключаюсь к обслуживающему экземпляру. Я могу проанализировать все значения и пройтись по коду, используя стандартные команды pdb, такие как n, s и т.д.

In [2]: import epdb; epdb.connect()
(Epdb) request
<WSGIRequest
path:/foo,
GET:<QueryDict: {}>, 
POST:<QuestDict: {}>,
...
>
(Epdb) request.session.session_key
'i31kq7lljj3up5v7hbw9cff0rga2vlq5'
(Epdb) list
 85         raise some_error.CustomError()
 86 
 87     # Example login view
 88     def login(request, username, password):
 89         import epdb; epdb.serve()
 90  ->     return my_login_method(username, password)
 91
 92     # Example view to show session key
 93     def get_session_key(request):
 94         return request.session.session_key
 95

И многое другое, что вы можете узнать о вводе справки epdb в любое время.

Если вы хотите обслуживать или подключаться к нескольким экземплярам epdb одновременно, вы можете указать порт для прослушивания (по умолчанию 8080). То есть.

import epdb; epdb.serve(4242)

>> import epdb; epdb.connect(Host='192.168.3.2', port=4242)

Хост по умолчанию «localhost», если не указан. Я добавил это здесь, чтобы продемонстрировать, как вы можете использовать это для отладки чего-то другого, кроме локального экземпляра, например сервера разработки в вашей локальной сети. Очевидно, что если вы сделаете это, будьте осторожны, так как заданная трассировка никогда не попадет на ваш рабочий сервер!

В качестве краткого примечания, вы все равно можете сделать то же самое, что и принятый ответ с помощью epdb (import epdb; epdb.set_trace()), но я хотел бы выделить функциональность подачи, поскольку я нашел его таким полезным.

6
Jacinda

Я использую PyCharm и различные инструменты отладки. Также есть хорошие статьи о том, как легко настроить эти вещи для новичков. Вы можете начать здесь. Рассказывает об отладке PDB и GUI в целом с проектами Django. Надеюсь, что кто-то извлечет из них пользу.

3
garmoncheg

Добавьте import pdb; pdb.set_trace() в соответствующую строку в коде Python и выполните его. Выполнение остановится с помощью интерактивной оболочки. В командной консоли вы можете выполнить код Python (например, переменные печати) или использовать такие команды, как:

  • c продолжить исполнение
  • n шаг к следующей строке в той же функции
  • s переход к следующей строке в этой функции или вызываемой функции
  • q выйти из отладчика/выполнения

Также смотрите: https://poweruser.blog/setting-a-breakpoint-in-python-438e23fe6b28

2
Chris

Если вы используете Aptana для разработки Django, посмотрите это: http://www.youtube.com/watch?v=qQh-UQFltJQ

Если нет, подумайте об использовании.

2
user1144616

Для тех, кто может случайно добавить pdb в живые коммиты, я могу предложить следующее расширение ответа #Koobz:

@register.filter 
def pdb(element):
    from Django.conf import settings
    if settings.DEBUG:    
        import pdb
        pdb.set_trace()
    return element
2
MontyThreeCard

Большинство опций уже упоминалось . Чтобы напечатать контекст шаблона, я создал для этого простую библиотеку . См. https://github.com/edoburu/Django-debugtools

Вы можете использовать его для печати контекста шаблона без какой-либо конструкции {% load %}:

{% print var %}   prints variable
{% print %}       prints all

Он использует настраиваемый формат pprint для отображения переменных в теге <pre>.

2
vdboor

Я нахожу, что Visual Studio Code отлично подходит для отладки приложений Django. Стандартные параметры python launch.json запускают python manage.py с подключенным отладчиком, поэтому вы можете устанавливать точки останова и шагать по своему коду по своему усмотрению.

2
Noah MacCallum

Один из лучших вариантов отладки кода Django - через wdb: https://github.com/Kozea/wdb

wdb работает с python 2 (2.6, 2.7), python 3 (3.2, 3.3, 3.4, 3.5) и pypy. Более того, можно отлаживать программу на python 2 с сервером wdb, работающим на python 3, и наоборот или отлаживать программу, запущенную на компьютере с сервером отладки, работающим на другом компьютере, внутри веб-страницы на третьем компьютере! __. Более того, теперь возможно приостановить текущий запущенный процесс/поток Python, используя внедрение кода из веб-интерфейса. (Для этого требуются gdb и ptrace) Другими словами, это очень улучшенная версия pdb прямо в вашем браузере с функциями Nice.

Установите и запустите сервер, и в своем коде добавьте:

import wdb
wdb.set_trace()

По мнению автора, основными отличиями в отношении pdb являются:

Для тех, кто не знает проект, wdb - это отладчик Python, такой как pdb, но с отличным веб-интерфейсом и множеством дополнительных функций, таких как:

  • Подсветка синтаксиса источника 
  • Визуальные точки останова 
  • Интерактивное завершение кода с использованием джедая 
  • Постоянные точки останова 
  • Глубокая проверка объектов с помощью мыши Поддержка многопоточности/многопроцессорности
  • Удаленная отладка
  • Смотреть выражения 
  • В редакции кода отладчика 
  • Интеграция популярных веб-серверов в случае ошибки 
  • В случае прерывания исключения во время трассировки (не после вскрытия), например, в отличие от отладчика werkzeug
  • Взлом в запущенных в настоящий момент программах посредством внедрения кода (в поддерживаемых системах)

У него отличный браузерный пользовательский интерфейс. Радость в использовании! :)

2
fessacchiotto

я настоятельно рекомендую использовать PDB.

import pdb
pdb.set_trace()

Вы можете проверить все значения переменных, перейти к функции и многое другое . https://docs.python.org/2/library/pdb.html

для проверки всех видов запросов, ответов и обращений к базе данных. Я использую Django-debug-toolbar https://github.com/Django-debug-toolbar/Django-debug-toolbar

1
nitansh bareja

Как уже упоминалось в других постах, здесь - установка точек останова в вашем коде и просмотр кода, чтобы увидеть, ведет ли он себя так, как вы ожидали, - отличный способ изучить что-то вроде Django, пока вы не поймете, как все это ведет себя - и каков ваш код делается.

Для этого я бы рекомендовал использовать WingIde. Как и в других упомянутых средах разработки. Отличный и простой в использовании, удобный макет, а также простота установки точек останова, оценка/изменение стека и т.д. Идеально подходит для визуализации того, что делает ваш код, когда вы проходите через него. Я большой поклонник этого.

Также я использую PyCharm - он имеет отличный статический анализ кода и может иногда помочь обнаружить проблемы, прежде чем вы поймете, что они есть.

Как уже упоминалось, Django-debug-toolbar имеет важное значение - https://github.com/Django-debug-toolbar/Django-debug-toolbar

И хотя это явно не инструмент отладки или анализа - одним из моих любимых является Промежуточное программное обеспечение для печати, доступное в Django Snippets по адресу https://djangosnippets.org/snippets/290/

Это отобразит запросы SQL, сгенерированные вашим представлением. Это даст вам хорошее представление о том, что делает ORM, и если ваши запросы эффективны или вам нужно переработать код (или добавить кеширование).

Я считаю его бесценным для отслеживания производительности запросов при разработке и отладке моего приложения. 

Еще один совет - я немного изменил его для собственного использования, чтобы показывать только сводку, а не оператор SQL .... Поэтому я всегда использую его при разработке и тестировании. Я также добавил, что если len (connection.queries) больше, чем предопределенный порог, отображается дополнительное предупреждение.

Затем, если я улавливаю что-то плохое (с точки зрения производительности или количества запросов), я возвращаюсь к полному отображению операторов SQL, чтобы точно увидеть, что происходит. Очень удобно, когда вы работаете над большим проектом Django с несколькими разработчиками.

1
IanH

Во время разработки добавляем быстрый

assert False, value

может помочь диагностировать проблемы в представлениях или где-либо еще, без необходимости использовать отладчик.

0
Udi

Исходя из собственного опыта, есть два пути:

  1. использовать ipdb , который является расширенным отладчиком, любит pdb.

    import ipdb;ipdb.set_trace()

  2. используйте Django Shell, просто используйте команду ниже. Это очень полезно, когда вы разрабатываете новый вид.

    python manage.py Shell

0
Mark White

Дополнительное предложение. 

Вы можете использовать тесты носа и pdb вместе, скорее добавляя pdb.set_trace() в свои представления вручную. Преимущество состоит в том, что вы можете наблюдать ошибки при их первом запуске, возможно, в стороннем коде.

Вот ошибка для меня сегодня.

TypeError at /db/hcm91dmo/catalog/records/

render_option() argument after * must be a sequence, not int

....


Error during template rendering

In template /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/crispy_forms/templates/bootstrap3/field.html, error at line 28
render_option() argument after * must be a sequence, not int
18  
19          {% if field|is_checkboxselectmultiple %}
20              {% include 'bootstrap3/layout/checkboxselectmultiple.html' %}
21          {% endif %}
22  
23          {% if field|is_radioselect %}
24              {% include 'bootstrap3/layout/radioselect.html' %}
25          {% endif %}
26  
27          {% if not field|is_checkboxselectmultiple and not field|is_radioselect %}
28  

      {% if field|is_checkbox and form_show_labels %}

Теперь я знаю, что это означает, что я обманываю конструктор для формы, и у меня даже есть хорошее представление о том, какое поле является проблемой. Но можно ли использовать pdb, чтобы увидеть, на что жалуются хрустящие формы, внутри шаблона ?

Да, я могу. Использование параметра --pdb при тестировании носа:

tests$ nosetests test_urls_catalog.py --pdb

Как только я нажимаю на любое исключение (в том числе обработанное изящно), pdb останавливается там, где это происходит, и я могу посмотреть вокруг.

  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django/forms/forms.py", line 537, in __str__
    return self.as_widget()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django/forms/forms.py", line 593, in as_widget
    return force_text(widget.render(name, self.value(), attrs=attrs))
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django/forms/widgets.py", line 513, in render
    options = self.render_options(choices, [value])
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django/forms/widgets.py", line 543, in render_options
    output.append(self.render_option(selected_choices, *option))
TypeError: render_option() argument after * must be a sequence, not int
INFO lib.capture_middleware log write_to_index(http://localhost:8082/db/hcm91dmo/catalog/records.html)
INFO lib.capture_middleware log write_to_index:end
> /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/Django/forms/widgets.py(543)render_options()
-> output.append(self.render_option(selected_choices, *option))
(Pdb) import pprint
(Pdb) pprint.PrettyPrinter(indent=4).pprint(self)
<Django.forms.widgets.Select object at 0x115fe7d10>
(Pdb) pprint.PrettyPrinter(indent=4).pprint(vars(self))
{   'attrs': {   'class': 'select form-control'},
    'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]],
    'is_required': False}
(Pdb)         

Теперь ясно, что мой аргумент выбора для хрустящего конструктора поля был как список внутри списка, а не как список/кортеж кортежей.

 'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]

Замечательно то, что этот pdb находится в коде crispy, а не в моем, и мне не нужно было вставлять его вручную.

0
JL Peyret

используйте pdb или ipdb. Разница между этими двумя аспектами заключается в том, что ipdb поддерживает автозаполнение.

для PDB

import pdb
pdb.set_trace()

для ipdb

import ipdb
ipdb.set_trace()

Для выполнения новой строки нажмите клавишу n, для продолжения нажмите клавишу c . Проверьте дополнительные параметры с помощью help(pdb)

0
Abdul Gaffar