这就是我的方式:
{{ 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]" />
这样的数组然后计算其长度时呢?
答案 0 :(得分:5)
Django中有一些地方“原因”是因为它是如何为Django管理应用程序实现的,我相信这是其中之一。因此答案是他们希望你实现自己的javascript。
请参阅此问题Dynamically adding a form...了解更多javascript观点。
还有两个可插拔的应用程序django-dynamic-formset和django-dinamyc-form,直到现在才查看第一个应用程序时我才看到。
答案 1 :(得分:4)
这个问题有点陈旧,但我花了一段时间来解决这个问题。
我建议将模板中的formset.empty_form渲染为隐藏字段,并在javascript中引用此字段。
这是django管理站点中复杂的动态formset示例: (但请注意,它尚未更新为使用empty_form ....)
[JS] http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/media/js/inlines.js
答案 2 :(得分:1)
这是因为formset已经创建为只使用通常的HTTP工作流程无javascript 。
Django与javascript无关。
如果您想添加一些javascript,可以使用dedicated jquery plugin。
答案 3 :(得分:1)
在我的情况下。我使用了插件django-dynamic-formset(https://code.google.com/p/django-dynamic-formset/wiki/Usage)
并修改了“添加”选项并且运作良好。
$('#formset-table tbody tr').formset({ prefix: '{{ formset.prefix }}', formCssClass: '{{ formset.prefix }}-inlineformset', added: function(obj_tr){
var form = $(obj_tr).html().replace(/\-(\w+)\-(\w+)(fix__)\-/g, '-');
$(obj_tr).html(form);
},
此正则表达式替换字符串[prefix] - 前缀 peer' - '
可能不是最好的解决方案,但有效。
答案 4 :(得分:1)
使用formset.empty_form
作为字符串时,有些情况可能存在XSS,将'__prefix__'
替换为实际的formset表单索引。我的可插拔应用程序将formset.empty_form
转换为Knockout.js模板,然后通过自定义Knockout.js绑定进行克隆。此外,Knockout.js会自动重新计算表单字段ID索引,当在提交了inlineformsets的整个表单之前动态删除新添加的formset表单时。这是文档:
Knockout.js绑定在使用内联Javascript加载自定义字段时也会阻止XSS。