Comment faire un formset dynamique à Django?

, Voici la façon dont je suis en train de faire:

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

et voici le 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);
});

ce qui me dérange particulièrement, c'est que j'ai dû écrire moi-même cette étiquette de modèle escapejs . Il enlève juste toutes les nouvelles lignes et échappe à toutes les guillemets simples de sorte qu'il ne gâche pas ma corde. Mais qu'est-ce que les fabricants de Django attendaient de nous dans cette situation? Et pourquoi ont-ils cette TOTAL_FORMS champ caché, alors qu'ils pourraient juste un tableau comme <input name="my_form_field[0]" /> et puis compté sa longueur à la place?

18
demandé sur mpen 2010-03-01 06:19:19

5 réponses

il y a quelques endroits à Django où" la raison pour laquelle " est parce que c'est comme ça que ça a été implémenté pour L'application Admin Django, et je crois que c'est l'un d'eux. Ainsi, la réponse est qu'ils s'attendent à ce que vous implémentiez votre propre javascript.

voir cette question ajout dynamique d'un formulaire... pour plus d'idées javascript.

Il y a aussi deux enfichable applications disponibles, django-dynamique-formset et django-dinamyc-forme que je n'avais pas vu jusqu'à présent en regardant vers le haut de la première.

5
répondu Van Gale 2017-05-23 12:16:52

Cette question est un peu vieux, mais il m'a fallu un certain temps pour comprendre cela.

je suggère de rendre formset.empty_form dans votre template comme un champ caché, et référencement de ce champ dans votre javascript.

voici un exemple de formset dynamique compliqué du site admin django: (mais notez qu'il n'a pas été mis à jour pour utiliser empty_form....)

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

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

4
répondu bsk 2010-08-11 00:44:46

c'est parce que formset ont été créés pour fonctionner sans javascript , en utilisant seulement le flux HTTP habituel.

Django est un agnostique javascript.

si vous voulez ajouter du javascript au mix, vous pouvez utiliser le dédié au plugin jquery .

1
répondu e-satis 2012-01-04 19:55:08

dans mon cas. j'ai utilisé le plugin django-dynamic-formset ( https://code.google.com/p/django-dynamic-formset/wiki/Usage )

et a modifié l'option" ajouté " et a bien fonctionné.

        $('#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);

           },

cette expression régulière remplacer la chaîne [préfixe]- préfixe "1519120920 par les pairs" ' - '

n'est peut-être pas la meilleure solution, mais ça a marché.

1
répondu McQuade 2013-10-04 12:45:26

dans certains cas, il est possible d'utiliser XSS avec formset.empty_form comme chaîne de caractères, en remplaçant '__prefix__' par "formset form index". Mon application branchée convertit formset.empty_form en Knockout.js template qui est ensuite cloné via Knockout personnalisé.js liaisons. Aussi Knock-Out.js recalcule automatiquement les index d'id de champ de formulaire, lorsque le nouveau formset est supprimé dynamiquement avant que le formulaire entier avec les formetsinline n'ait été soumis. Voici la documentation:

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

K. O.js binding empêche également XSS lors du chargement des champs personnalisés avec Javascript en ligne.

1
répondu Dmitriy Sintsov 2016-03-18 08:06:37