Как бы вы создали динамический набор форм в Django? - PullRequest
18 голосов
/ 01 марта 2010

Вот как я это делаю:

{{ 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 ]

5 голосов
/ 01 марта 2010

В Django есть несколько мест, где «причина» в том, что именно так это было реализовано для приложения администратора Django, и я считаю, что это одно из них. Таким образом, ответ заключается в том, что они ожидают от вас реализации своего собственного javascript.

См. Этот ТАК вопрос Динамическое добавление формы ... для некоторых других идей JavaScript.

Есть также два подключаемых приложения: django-dynamic-formset и django-dinamyc-form , которые я не видел до сих пор, когда искал первое.

4 голосов
/ 11 августа 2010

Этот вопрос немного стар, но мне потребовалось время, чтобы понять это.

Я предлагаю отобразить formset.empty_form в вашем шаблоне как скрытое поле и ссылаться на это поле в вашем JavaScript.

Вот пример сложной динамической формы с сайта администратора django: (но учтите, что он не был обновлен для использования empty_form ....)

[УД] 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

1 голос
/ 18 марта 2016

В некоторых случаях возможен XSS при использовании formset.empty_form в качестве строки, заменяющей '__prefix__' на фактический индекс формы набора. Мое подключаемое приложение преобразует formset.empty_form в шаблон Knockout.js, который затем клонируется с помощью пользовательских привязок Knockout.js. Кроме того, Knockout.js автоматически пересчитывает индексы идентификатора поля формы, когда вновь добавленная форма набора форм динамически удаляется до того, как была отправлена ​​вся форма с inlineformsets. Вот документация:

https://django -jinja-knockout.readthedocs.org / о / последняя / forms.html # динамически добавлять новый связанный-formset-форма

Привязка Knockout.js также предотвращает XSS при загрузке пользовательских полей со встроенным Javascript.

1 голос
/ 04 октября 2013

в моем случае. я использовал плагин 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);

           },

это регулярное выражение заменяет строку [префикс] - префикс peer '-'

возможно, не лучшее решение, но сработало.

1 голос
/ 04 января 2012

Это потому, что набор форм был создан для работы без JavaScript , используя только обычный рабочий процесс HTTP.

Джанго не знает JavaScript.

Если вы хотите добавить javascript к миксу, вы можете использовать выделенный плагин jquery .

...