你会如何在Django中制作动态的formset?

时间:2010-03-01 03:19:19

标签: javascript django formsets

这就是我的方式:

{{ 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]" />这样的数组然后计算其长度时呢?

5 个答案:

答案 0 :(得分:5)

Django中有一些地方“原因”是因为它是如何为Django管理应用程序实现的,我相信这是其中之一。因此答案是他们希望你实现自己的javascript。

请参阅此问题Dynamically adding a form...了解更多javascript观点。

还有两个可插拔的应用程序django-dynamic-formsetdjango-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

[html模板] http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/templates/admin/edit_inline/tabular.html

答案 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表单时。这是文档:

https://django-jinja-knockout.readthedocs.org/en/latest/forms.html#dynamically-adding-new-related-formset-forms

Knockout.js绑定在使用内联Javascript加载自定义字段时也会阻止XSS。