Une suggestion supplémentaire.
Vous pouvez tirer parti nosetests et pdb ensemble, plutôt injecter pdb.set_trace()
dans vos vues manuellement. L'avantage est que vous pouvez observer les conditions d'erreur lors de leur premier démarrage, potentiellement dans du code tiers.
Voici une erreur pour moi aujourd'hui.
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 %}
Maintenant, je sais que cela signifie que j'ai gaffé le constructeur du formulaire, et j'ai même une bonne idée de quel champ est un problème. Mais, puis-je utiliser pdb pour voir de quoi se plaignent les formulaires croustillants dans un modèle ?
Oui je peux. Utilisation de la --pdb option sur nosetests:
tests$ nosetests test_urls_catalog.py --pdb
Dès que je frappe une exception (y compris celles gérées avec élégance), pdb s'arrête là où cela se produit et je peux regarder autour de moi.
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)
Maintenant, il est clair que mon argument de choix pour le constructeur de champ croustillant était comme s'il s'agissait d'une liste dans une liste, plutôt que d'une liste / d'un tuple de tuples.
'choices': [[('_', 'any type'), (7, (7, 'type 7', 'RECTYPE_TABLE'))]]
La chose intéressante est que ce pdb se déroule dans le code de crispy, pas le mien et je n'ai pas eu besoin de l'insérer manuellement.