Javascript 您将如何在 Django 中制作动态表单集?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2353710/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:54:22  来源:igfitidea点击:

How would you make a dynamic formset in Django?

javascriptdjangoformsets

提问by mpen

Here's the way I'm doing it:

这是我的做法:

{{ formset.management_form }}
<table>
    {% for form in formset.forms %}
        {{ form }}
    {% endfor %}
</table>
<a href="javascript:void(0)" id="add_form">Add Form</a>   

And here's the JS:

这是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);
});

What specifically bothers me is that I had to write that escapejstemplate tag myself. It just strips all newlines and escapes any single quotes so that it doesn't mess up my string. But what exactly did the Django makers expect us to do in this situation? And why do they have this TOTAL_FORMShidden field, when they could have just used an array like <input name="my_form_field[0]" />and then counted its length instead?

特别困扰我的是我必须自己编写escapejs模板标签。它只是去除所有换行符并转义任何单引号,以免弄乱我的字符串。但是在这种情况下,Django 的制作者究竟希望我们做什么呢?为什么他们有这个TOTAL_FORMS隐藏字段,当他们可以只使用一个数组<input name="my_form_field[0]" />然后计算它的长度时呢?

采纳答案by Van Gale

There are a few places in Django where "the reason why" is because that's how it was implemented for the Django admin app, and I believe this is one of them. Thus the answer is they expect you to implement your own javascript.

Django 中有几个地方“原因”是因为这就是 Django 管理应用程序的实现方式,我相信这是其中之一。因此,答案是他们希望您实现自己的 javascript。

See this SO question Dynamically adding a form...for some more javascript ideas.

请参阅此问题动态添加表单...了解更多 javascript 想法。

There are also two pluggable apps available, django-dynamic-formsetand django-dinamyc-formwhich I hadn't seen until just now when looking up the first one.

还有两个可插拔的应用程序可用,django-dynamic-formsetdjango-dinamyc-form,我直到刚才在查找第一个时才看到。

回答by bsk

This question is a bit old, but it took me a while to figure this out as well.

这个问题有点老了,但我也花了一段时间才弄明白。

I suggest rendering formset.empty_form in your template as a hidden field, and referencing this field in your javascript.

我建议将模板中的 formset.empty_form 渲染为隐藏字段,并在您的 javascript 中引用此字段。

Here's a complicated dynamic formset example from the django admin site: (but note that it has not been updated to use empty_form....)

这是来自 django 管理站点的复杂动态表单集示例:(但请注意,它尚未更新为使用 empty_form....)

[js] http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/media/js/inlines.js

[js] http://code.djangoproject.com/browser/django/trunk/django/contrib/admin/media/js/inlines.js

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

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

回答by e-satis

It's because formset have been created to work without javascript, using only the usual HTTP workflow.

这是因为 formset 已被创建为在没有 javascript 的情况下工作,仅使用通常的 HTTP 工作流程。

Django is javascript agnostic.

Django 与 JavaScript 无关。

If you want to add some javascript to the mix, you can use the dedicated jquery plugin.

如果你想添加一些 javascript,你可以使用专用的 jquery 插件

回答by McQuade

in my case. i used the plugin django-dynamic-formset (https://code.google.com/p/django-dynamic-formset/wiki/Usage)

就我而言。我使用了插件 django-dynamic-formset ( https://code.google.com/p/django-dynamic-formset/wiki/Usage)

and modified the option "added" and worked good.

并修改了“添加”选项并且效果很好。

        $('#formset-table tbody tr').formset({
            prefix: '{{ formset.prefix }}',
            formCssClass: '{{ formset.prefix }}-inlineformset',
            added: function(obj_tr){ 
        $('#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);

           },

this regular expression replace the string [prefix]-prefixpeer '-'

此正则表达式替换字符串 [prefix]-前缀peer '-'

maybe isn't the best solution, but worked.

也许不是最好的解决方案,但有效。

回答by Dmitriy Sintsov

There are some cases of possible XSS when using formset.empty_formas a string, replacing '__prefix__'to actual formset form index. My pluggable application converts formset.empty_forminto Knockout.js template which is then cloned via custom Knockout.js bindings. Also Knockout.js automatically re-calculates form field id indexes, when newly added formset form is dynamically deleted before the whole form with inlineformsets was submitted. Here is the documentation:

formset.empty_form用作字符串时,有一些可能的 XSS 情况,替换'__prefix__'为实际的表单集表单索引。我的可插入应用程序转换formset.empty_form为 Knockout.js 模板,然后通过自定义 Knockout.js 绑定进行克隆。Knockout.js 还会自动重新计算表单字段 id 索引,当新添加的表单集表单在提交带有内联表单集的整个表单之前被动态删除时。这是文档:

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

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

Knockout.js binding also prevents XSS when loading custom fields with inline Javascript.

当使用内联 Javascript 加载自定义字段时,Knockout.js 绑定还可以防止 XSS。