Tengo una forma frutas que tiene un objeto FieldList de los plátanos:Como: Generar dinámicamente CSRF token en WTForms con el frasco
bananas = FieldList(FormField(BananaForm))
En el frontend, en un principio, agrego uno de esos campos a la FieldList
form.append_entry()
Ahora con Javascript que lograron crear funciones, que se pueden añadir de forma dinámica (más una tecla) o eliminar (botón menos) el número de campos BananaForm que se pueden llenar con información.
FielstList crea automáticamente identificadores para todos sus campos. Así que hacer dinámica añadiendo con JS, duplico el código HTML y configurar el identificador del campo + = 1, como:
primer campo:
<tr>
<td><input id="bananas-0-originCountry" type="text" /></td>
</tr>
campo duplicado con + = 1:
<tr>
<td><input id="bananas-1-originCountry" type="text" /></td>
</tr>
Cuando los nombre así y envíen el formulario, WTForms reconocerá automáticamente los campos agregados en el back-end (funciona bien).
Hasta ahora todo bien, pero aquí está mi problema: Para que un formulario sea válido, tengo que agregar campos CSRF a cada WTForm. En la plantilla de Jinja hago esto con:
{{ form.hidden_tag() }}
Sin embargo, cuando acabo de copiar el código HTML con mi función js, me faltan los campos CSRF (porque hasta presentado, el objeto de formulario backend no sabe acerca de los FormFields agregados). Entonces, ¿cómo puedo generar estos campos CSRF dinámicamente? (¿Una solicitud de Ajax? En caso afirmativo, ¿cómo?)
Este debería ser un caso de uso estándar con formularios y matraz. Espero que mi descripción sea comprensible, si no, háganmelo saber. Cualquier ayuda apreciada!
ACTUALIZACIÓN: Aquí está mi código
JS-funciones Plantilla
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>
plantilla Jinja Macros:
{% 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 %}
Por el sonido de las cosas, el problema es con su HTML o JavaScript, ¿podría publicarlos para que podamos echar un vistazo más profundo? (Mi primera suposición es que está reemplazando el HTML interno de todo el formulario con el código regenerado, borrando así la etiqueta CSFR). –
Actualicé mi pregunta con el código.Descubrí que a pesar de que 'hidden_tag()' debería representar la etiqueta CSRF dentro de la copia
Respuesta
descubrí cómo funciona :
La etiqueta CSRF-Tag se puede copiar simplemente. La identificación se debe cambiar e incrementar en consecuencia, pero el hash puede permanecer igual.
No pensé que era posible tener muchos campos con el mismo hash CSRF-Tag, ¡pero en realidad sí!
Fuente
2012-08-19 08:34:11 kadrian
Cuestiones relacionadas