Ho una forma frutti che ha un oggetto FieldList per le banane:Howto: dinamicamente generare CSRF-token in WTForms con la boccetta
bananas = FieldList(FormField(BananaForm))
Nel frontend, inizialmente, aggiungo uno di quei campi a FieldList
form.append_entry()
Ora con JavaScript sono riuscito a creare funzioni, che possono aggiungere dinamicamente (pulsante più) o rimuovere (tasto meno) il numero di campi BananaForm che possono essere riempiti con le informazioni.
FielstList crea automaticamente ID per tutti i suoi campi. Quindi, per fare dinamica aggiungendo con js, ho duplicare il codice HTML e impostare il campo id + = 1, come:
primo campo:
<tr>
<td><input id="bananas-0-originCountry" type="text" /></td>
</tr>
campo duplicato con + = 1:
<tr>
<td><input id="bananas-1-originCountry" type="text" /></td>
</tr>
Quando li chiamo di conseguenza e invio il modulo, WTForms riconoscerà automaticamente i campi aggiunti nel backend (funziona bene).
Fin qui tutto bene, ma ecco il mio problema: Per un modulo valido, devo aggiungere campi CSRF a ogni WTForm. Nel modello di Jinja faccio questo con:
{{ form.hidden_tag() }}
Tuttavia, quando basta copiare il codice HTML con la mia funzione js, mi manca i CSRF-campi (perché fino presentata, l'oggetto modulo backend non lo sa circa i campi di campi aggiunti). Quindi, come posso generare questi campi CSRF in modo dinamico? (Una richiesta Ajax? Se sì, come?)
Questo dovrebbe essere un caso di uso standard con forme e fiaschi. Spero che la mia descrizione sia comprensibile, altrimenti ti prego di farmelo sapere. Qualsiasi aiuto apprezzato!
UPDATE: Ecco il mio codice
JS-funzioni Template
function addBanana(){
// clone and insert banana node
var node = document.getElementById("fruitTable");
var trs = node.getElementsByTagName("tr");
var tr = trs[trs.length-2];
var tr2 = tr.cloneNode(true);
tr.parentNode.insertBefore(tr2, tr);
// in order to increment label and input field ids
function plusone(str){
return str.replace(
new RegExp("-(\\d+)-", "gi"),
function($0, $1){
var i = parseInt($1) + 1;
return "-" + i + "-";
}
);
}
// change inputs
var inputs = tr.getElementsByTagName("input");
for (var i = 0; i < inputs.length; i++){
inputs[i].setAttribute("id", plusone(inputs[i].getAttribute("id")));
}
var minusbutton =
['<td>',
'<button class="btn" type="button" onClick="removeBanana()"><i class="icon-black icon-minus"></i></button>',
'</td>'
].join('\n');
// only append at the first add
// second add automatically copies minus button
if (trs.length < 6){
tr.innerHTML += minusbutton
}
}
function removeBanana(){
var node = document.getElementById("fruitTable");
var trs = node.getElementsByTagName("tr");
var tr = trs[trs.length-2];
var trParent = tr.parentNode;
trParent.removeChild(tr);
}
Jinja:
<form method="POST" action="newsubmit">
{{ form.hidden_tag() }}
<table id="fruitTable" class="table">
{{ render_field(form.description) }}
<tr><td><h3>Bananas</h3></td></tr>
{% set counter = 0 %}
{% for banana in form.bananas %}
<tr>
{{ banana.hidden_tag() }}
{% set counter = counter + 1%}
{% for field in banana if field.widget.input_type != 'hidden' %}
{{ render_field_oneline(field) }}
{% endfor %}
{% if counter > 1 %}
<td>
<button class="btn" type="button" onClick="removeBanana()"><i class="icon-black icon-minus"></i></button>
</td>
{% endif %}
</tr>
{% endfor %}
<tr><td></td><td><button class="btn" type="button" onClick="addBanana()"><i class="icon-black icon-plus"></i></button></td></tr>
</table>
<input class="btn btn-primary" style="margin-left:300px;"type="submit" value="Submit" />
</form>
Jinja Macro dei modelli:
{% macro render_field_oneline(field) %}
<td>{{ field.label }}</td>
<td>{{ field(**kwargs)|safe }}
{% if field.errors %}
<ul class=errors>
{% for error in field.errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
</td>
{% endmacro %}
{% macro render_field(field) %}
<tr>
{{ render_field_oneline(field) }}
</tr>
{% endmacro %}
Dal suono delle cose il problema è con il tuo codice HTML o il tuo JavaScript - potresti postare quelli in modo che possiamo dare un'occhiata più profonda? (La mia prima ipotesi è che stai sostituendo l'intero codice HTML interno del modulo con il tuo codice rigenerato cancellando così il tag CSFR). –
Ho aggiornato la mia domanda con il codice.Ho scoperto che nonostante 'hidden_tag()' dovrebbe rendere il tag CSRF all'interno del copiato
risposta
ho scoperto come funziona :
Il tag CSRF può essere semplicemente copiato. L'id deve essere modificato e incrementato di conseguenza, ma l'hash potrebbe rimanere lo stesso.
Non pensavo fosse possibile avere molti campi con lo stesso hash del tag CSRF, ma in realtà lo fa!
fonte
2012-08-19 08:34:11 kadrian
Problemi correlati