Así es como lo hago, usando jQuery :
Mi plantilla:
<h3>My Services</h3>
{{ serviceFormset.management_form }}
{% for form in serviceFormset.forms %}
<div class='table'>
<table class='no_error'>
{{ form.as_table }}
</table>
</div>
{% endfor %}
<input type="button" value="Add More" id="add_more">
<script>
$('#add_more').click(function() {
cloneMore('div.table:last', 'service');
});
</script>
En un archivo javascript:
function cloneMore(selector, type) {
var newElement = $(selector).clone(true);
var total = $('#id_' + type + '-TOTAL_FORMS').val();
newElement.find(':input').each(function() {
var name = $(this).attr('name').replace('-' + (total-1) + '-','-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
});
newElement.find('label').each(function() {
var newFor = $(this).attr('for').replace('-' + (total-1) + '-','-' + total + '-');
$(this).attr('for', newFor);
});
total++;
$('#id_' + type + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
}
Que hace:
cloneMoreacepta selectorcomo primer argumento, y typeof formset como el segundo. Lo que selectordebería hacer es pasarle lo que debería duplicar. En este caso, lo paso div.table:lastpara que jQuery busque la última tabla con una clase de table. La :lastparte de esto es importante porque selectortambién se usa para determinar después de qué se insertará el nuevo formulario. Es más que probable que lo desee al final del resto de los formularios. El typeargumento es para que podamos actualizar el management_formcampo, en particular TOTAL_FORMS, así como los campos de formulario reales. Si tiene un conjunto de formularios lleno de, por ejemplo, Clientmodelos, los campos de administración tendrán ID id_clients-TOTAL_FORMSy id_clients-INITIAL_FORMS, mientras que los campos de formulario estarán en un formato de id_clients-N-fieldnameconNsiendo el número de formulario, comenzando con 0. Así, con el typeargumento de las cloneMoremiradas de la función de cuántas formas hay actualmente, y pasa a través de cada entrada y etiqueta dentro de la nueva forma de la sustitución de todos los nombres de campo / nº ID de algo así como id_clients-(N)-nameque id_clients-(N+1)-namey así sucesivamente. Una vez finalizado, actualiza el TOTAL_FORMScampo para reflejar el nuevo formulario y lo agrega al final del conjunto.
Esta función es particularmente útil para mí porque la forma en que está configurada me permite usarla en toda la aplicación cuando quiero proporcionar más formularios en un conjunto de formularios, y no hace que necesite tener un formulario oculto de "plantilla" para duplicar siempre que lo pase, el nombre del formulario y el formato en que se presentan los formularios. Espero eso ayude.