Django formset, видимо, печатает только первую форму в шаблоне (из-за неверной разметки) - PullRequest
1 голос
/ 09 февраля 2012

[ Редактировать: Смотрите мой ответ ниже - причина этой проблемы - неверная разметка, и браузеры очень стараются это скрыть. ]

У меня есть набор форм, который определенно должен содержать две формы, но по какой-то причине в шаблоне печатается только одна форма.

Это строка шаблона:

<tr id="existing_docs_row"><td colspan="2">{{ existing_articles.management_form }}{% for f in existing_articles %}<div>{{ f }}</div>{% endfor %}</td></tr>

Я получаю точно такое же поведение (без тегов div) с:

<tr id="existing_docs_row"><td colspan="2">{{ existing_articles }}}</td></tr>

Форма управления и первая форма созданы, но не вторая. Вот что я получаю в своем браузере:

<input type="hidden" id="id_form-TOTAL_FORMS" value="2" name="form-TOTAL_FORMS"><input type="hidden" id="id_form-INITIAL_FORMS" value="2" name="form-INITIAL_FORMS"><input type="hidden" id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS"><div><div class="selected_row " id="selected_row"><span class="formlabel"></span><ul>
<li><label for="id_form-0-selected_0"><input type="radio" name="form-0-selected" value="True" id="id_form-0-selected_0"> </label></li>
</ul></div>
<div class="original_filename_row " id="original_filename_row"><span class="formlabel"><span id="for-id_form-0-original_filename-">Original filename:</span></span><div id="id_form-0-original_filename" name="form-0-original_filename">FakeExampleCompanyName.docx</div></div>
<div class="tags_row " id="tags_row"><span class="formlabel"><span id="for-id_form-0-tags-">Tags:</span></span><div id="id_form-0-tags" name="form-0-tags" class="tagarea"><span class="tagitem">England and Wales</span> <span class="tagitem">Private company limited by shares</span> <span class="tagitem">Model articles with amendments</span></div></div>

Разбиение в представлении и печать набора форм показывает, что он содержит две формы (existing_template_formset - это имя набора форм внутри представления):

>>> print existing_template_formset <input type="hidden" name="form-TOTAL_FORMS" value="2" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS" /> 
<div id="selected_row" class="selected_row "> <span class="formlabel"></span><ul> <li><label for="id_form-0-selected_0"><input type="radio" id="id_form-0-selected_0" value="True" name="form-0-selected" /> </label></li> </ul></div> <div id="original_filename_row" class="original_filename_row "><span class="formlabel"><span id="for-id_form-0-original_filename-">Original filename:</span></span><div name="form-0-original_filename" id="id_form-0-original_filename">FakeExampleCompanyName.docx</div></div> <div id="tags_row" class="tags_row "><span class="formlabel"><span id="for-id_form-0-tags-">Tags:</span></span><div class="tagarea" name="form-0-tags" id="id_form-0-tags" ><span class="tagitem" >England and Wales</span> <span class="tagitem" >Private company limited by shares</span> <span class="tagitem" >Model articles with amendments</span></div></div> <tr><th></th><td><input type="hidden" name="form-0-id" id="id_form-0-id" /></td></tr> 
<div id="selected_row" class="selected_row "><span class="formlabel"></span><ul> <li><label for="id_form-1-selected_0"><input type="radio" id="id_form-1-selected_0" value="True" name="form-1-selected" /> </label></li> </ul></div> <div id="original_filename_row" class="original_filename_row "><span class="formlabel"><span id="for-id_form-1-original_filename-">Original filename:</span></span><div name="form-1-original_filename" id="id_form-1-original_filename" >FakeExampleCompanyName.docx</div></div> <div id="tags_row" class="tags_row "><span class="formlabel"><span id="for-id_form-1-tags-">Tags:</span></span><div class="tagarea" name="form-1-tags" id="id_form-1-tags" ></div></div> <tr><th></th><td><input type="hidden" name="form-1-id" id="id_form-1-id" /></td></tr>

>>> len(existing_template_formset) 2

Как видите, в обоих случаях общее количество форм в наборе формул равно 2 (как видно из формы управления), но второй просто не генерируется.

Кто-нибудь сталкивался с этим раньше? Как мне это исправить?

Я использую django 1.3.1 на python 2.7.2 для Windows.

Для полноты вот код, который создает форму:

class ExistingTemplateFormset(modelformset_factory(ArticlesTemplate, extra = 0, form=ExistingTemplateForm)):
    def __init__(self, *args, **kwargs):
        super(ExistingTemplateFormset, self).__init__(*args, **kwargs)
        for x in self:
            x.fields['id'].widget = forms.HiddenInput()

            x.fields['original_filename'].editable = False
            x.fields['original_filename'].widget = SpanWidget(tag = u'div')


            x.fields['tags'].widget= TagArea()
            x.fields['tags'].help_text = u''

(TagArea и SpanWidget существуют)

На виде:

existing_template_formset = ExistingTemplateFormset(queryset = the_organisation.get_template_articles())

1 Ответ

2 голосов
/ 09 февраля 2012

Читатели с острым взглядом (которые, как оказалось, не включают меня, отсюда и эту проблему) заметят, что мой вывод включает в конце каждой формы:

`<tr><th></th><td><input type="hidden" name="form-0-id" id="id_form-0-id" /></td></tr>` 

Теперь, когда это подставляется в <tr id="existing_docs_row"><td colspan="2">{{ existing_articles.management_form }}{% for f in existing_articles %}<div>{{ f }}</div>{% endfor %}</td></tr>, это приводит к неверной разметке (tr внутри tr!).

Итак, получается, что шаблон был , генерирующий вторую форму, но методы исправления ошибок браузера (в chrome, игнорируя много неверной разметки; в firefox, перемещая вторую форму в другое место) в DOM) создало впечатление, что вторая форма не генерируется.

Подводя итог: просто изучение DOM вводит меня в заблуждение. Попробуйте заставить ваш браузер подавиться ошибками и посмотрите на необработанную разметку.

...