Вот способ, которым я делаю его:
{{ formset.management_form }}
<table>
{% for form in formset.forms %}
{{ form }}
{% endfor %}
</table>
<a href="javascript:void(0)" id="add_form">Add Form</a>
И вот JS:
var form_count = {{formset.total_form_count}};
$('#add_form').click(function() {
form_count++;
var form = '{{formset.empty_form|escapejs}}'.replace(/__prefix__/g, form_count);
$('#forms').append(form)
$('#id_form-TOTAL_FORMS').val(form_count);
});
То, что конкретно беспокоит меня, - то, что я должен был записать это escapejs
тег шаблона самостоятельно. Это просто разделяет все новые строки и выходит из любых одинарных кавычек так, чтобы это не портило мою строку. Но что точно производители Django ожидали, что мы сделаем в этой ситуации? И почему у них есть это TOTAL_FORMS
скрытое поле, когда они, возможно, просто использовали массив как <input name="my_form_field[0]" />
и затем считаемый его длина вместо этого?
В Django есть несколько мест, где "причина почему" заключается в том, что так было реализовано для приложения Django admin, и я полагаю, что это одно из них. Таким образом, ответ заключается в том, что они ожидают, что вы реализуете свой собственный javascript.
См. этот вопрос SO Динамическое добавление формы... для некоторых других идей javascript.
Есть также два подключаемых приложения, django-dynamic-formset и django-dinamyc-form, которые я не видел до сих пор, когда искал первое.
Этот вопрос немного устарел, но мне тоже потребовалось время, чтобы разобраться в нем.
Я предлагаю отобразить formset.empty_form в вашем шаблоне как скрытое поле и сделать ссылку на это поле в вашем javascript.
Вот сложный пример динамического набора форм с сайта администратора django: (но обратите внимание, что он не был обновлен для использования empty_form ....)
[js] http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/media/js/inlines.js
[шаблон HTML] http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/templates/admin/edit_inline/tabular.html