Статьи

Установка точек останова в шаблонах HTML в Python

Python предлагает множество различных шаблонизаторов для разработки веб-приложений, чтобы преобразовать логику представления в код HTML на сервере, а затем отправить полученный HTML-код в веб-браузер. Когда вы имеете дело со сложными шаблонами страниц, особенно при использовании сторонних библиотек, часто путают, какие переменные контекста шаблона доступны и что они съели. В этом случае лучший метод отладки — вставить точку останова в шаблон страницы и проверить переменные в контексте времени выполнения. Этот очень полезный «продвинутый» метод отладки не известен многим людям, особенно если они происходят из фона, где инструменты отладки командной строки не были нормой.

1. Python отладка

Python предлагает отладчик командной строки pdb из коробки. Я рекомендую использовать более продвинутую версию ipdb , которая поставляется с правильной историей команд, цветными трассировками и поддержкой завершения табуляции / клавиши со стрелкой ( хотя, похоже, существует проблема при использовании ipdb с многопоточными / автозагрузочными программами ). Также существует более GUIful, но все еще на основе терминала, pudb . Eclipse + PyDev предлагает поддержку удаленной отладки с полным графическим интерфейсом .

Прочитайте некоторые руководства по отладке командной строки, если вы не знакомы с этой концепцией. Особенно, как проверять локальные переменные с помощью команд locals (), dir (object), для i в dict.items (): print я попал в руки .

2. Установка точки останова в шаблонах Django

Вот пример того, как создать тег точки останова для шаблонов Django, а затем обойти и отладить ваши шаблоны. В этом примере я отлаживаю отображение поля django-crispy-форм .

Сначала нам нужно создать собственный тег шаблона Django, вызывающий pdb , потому что вы не можете запускать произвольные фрагменты Python непосредственно из шаблонов Django. Код здесь основан на примере на djangosnippets.org .

templatetags / debug.py

# -*- coding: utf-8 -*-
#
# http://djangosnippets.org/snippets/1550/
#

import pdb as pdb_module

from django.template import Library, Node

register = Library()

class PdbNode(Node):

    def render(self, context):
        pdb_module.set_trace()
        return ''

@register.tag
def pdb(parser, token):
    return PdbNode()

Затем мы используем этот тег нашего шаблона:

{% load crispy_forms_field %}
{% load debug %}

{% if field.is_hidden %}
    {{ field }}
{% else %}

    <div>
        <div>
            {{ field.long_help }}
            {% pdb %}
        </div>
    </div>
{% endif %}

Мы обычно запускаем Django с manage.py runserver и встречаем эту точку останова при рендеринге шаблона.

Снимок экрана 2013-05-16 в 9.36.06 утра

Теперь мы можем посмотреть, какие переменные доступны в шаблоне и что они съели.

(Pdb) locals().keys()
['self', 'context']
(Pdb) context.__class__
<class 'django.template.context.RequestContext'>

Итак, у нас есть доступные переменные шаблона в локальной переменной под названием context (имеет смысл, теперь мы в нашем коде templatetag.py ).

(Pdb) for i in dir(context): print i
...
_reset_dicts
autoescape
current_app
dicts
get
has_key
new
pop
push
render_context
update
use_l10n
use_tz

Кажется, есть способ получить доступ ко всем переменным шаблона:

(Pdb) for d in context.dicts: print d.keys()
[]
['csrf_token']
['request']
['perms', 'user']
['debug', 'sql_queries']
['LANGUAGES', 'LANGUAGE_BIDI', 'LANGUAGE_CODE']
['MEDIA_URL']
['STATIC_URL']
['TIME_ZONE']
['messages']
['downtime']
['block']
['flat_attrs', 'inputs', 'csrf_token', 'form_id', 'form_error_title', 
'form_action', 'error_text_inline', 'html5_required', 'help_text_inline', 
'formset_error_title', 'form_style', 'form_method', 'form_show_errors', 
'is_formset', 'form_tag', 'attrs', 'form_attrs', 'form_class']

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

(Pdb) context["field"]
<django.forms.forms.BoundField object at 0x1038ae590>

(Pdb) for i in context["field"].__dict__.items(): print i
('html_initial_name', u'initial-ad-xxx_type')
('form', <xxx.Form object at 0x103064c10>)
('html_name', 'ad-xxx_type')
('html_initial_id', u'initial-ad-id_ad-xxx_type')
('label', u'Foobar')
('field', <django.forms.fields.TypedChoiceField object at 0x103062e50>)
('help_text', '')
('name', 'xxx_type')

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

3. Другие шаблоны

Смотрите также пример для шаблонов Chameleon . К сожалению , из-за безопасности Plone не может поддерживать этот метод отладки .