代码之家  ›  专栏  ›  技术社区  ›  mpen

如何在Django中创建动态表单集?

  •  18
  • mpen  · 技术社区  · 15 年前

    我是这样做的:

    {{ 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 回复  |  直到 7 年前
        1
  •  5
  •   Community CDub    8 年前

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

    看到这个问题 Dynamically adding a form... 更多的javascript想法。

    还有两个可插拔的应用程序, django-dynamic-formset django-dinamyc-form 直到现在我才看到它。

        2
  •  4
  •   bsk    15 年前

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

    我建议将模板中的formset.empty_表单呈现为隐藏字段,并在JavaScript中引用该字段。

    下面是django管理站点中一个复杂的动态表单集示例: (但请注意,它尚未更新为使用空的_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

        3
  •  1
  •   Bite code    13 年前

    因为表单集是为工作而创建的 没有javascript ,仅使用常规的HTTP工作流。

    Django是Javascript不可知论者。

    如果要向组合中添加一些javascript,可以使用 dedicated jquery plugin .

        4
  •  1
  •   McQuade    12 年前

    以我为例。我使用了插件django动态表单集( 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]。- 前缀 同侪-

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

        5
  •  1
  •   Dmitriy Sintsov    9 年前

    使用时可能存在一些XSS情况 formset.empty_form 作为字符串,替换 '__prefix__' 到实际的表单集表单索引。我的可插拔应用程序转换 formset.empty表格 进入knockout.js模板,然后通过自定义knockout.js绑定进行克隆。当新添加的表单集表单在提交具有inlineformset的整个表单之前被动态删除时,knockout.js还会自动重新计算表单字段ID索引。文件如下:

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

    在用内联javascript加载自定义字段时,knockout.js绑定还可以防止XSS。