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

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

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

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

27 ответов

Решение

Есть множество способов сделать это, но самый простой - просто использовать отладчик 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, предложенного hangtwenty.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Я толкнул 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, материалы приветствуются, конечно.

Самый простой способ отладки 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. Наслаждайся этим.

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

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

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

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

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

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

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

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

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

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

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

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

import IPython; IPython.embed()

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

Я только что нашел 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 из командной строки или путем импорта в качестве модуля.

Я настоятельно рекомендую 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()), но я хотел бы подчеркнуть функциональность подачи, поскольку я нашел ее очень полезной.

Один из лучших вариантов отладки кода 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 прямо в вашем браузере с приятными функциями.

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

import wdb
wdb.set_trace()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    import ipdb;ipdb.set_trace()

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

    python manage.py shell

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

import pdb
pdb.set_trace()

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

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

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

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

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

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

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

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

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

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

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

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

для PDB

import pdb
pdb.set_trace()

для ipdb

import ipdb
ipdb.set_trace()

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

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

assert False, value

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

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

Вы можете использовать тесты носа и 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, а не в моем, и мне не нужно было вставлять его вручную.

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