Howto :Динамическое создание CSRF -Токен в WTForms с помощью Flask

У меня есть форма фруктов, в которой есть один объект FieldList для бананов :

bananas = FieldList(FormField(BananaForm))

. Сначала во внешнем интерфейсе я добавляю одно из этих полей в FieldList

form.append_entry()

. Теперь с помощью Javascript мне удалось создать функции, которые могут динамически добавлять (кнопку плюс )или удалять (кнопку минус )количество полей BananaForm, которые могут быть заполнены информацией.

FielstList автоматически создает идентификаторы для всех своих полей. Итак, чтобы сделать динамическое добавление с помощью js, я дублирую код HTML и устанавливаю идентификатор поля += 1, например:

первое поле:

<tr>
  <td><input id="bananas-0-originCountry" type="text" /></td>
</tr>

дублированное поле с += 1:

<tr>
  <td><input id="bananas-1-originCountry" type="text" /></td>
</tr>

Когда я назову их соответствующим образом и отправлю форму, WTForms автоматически распознает добавленные поля в бэкенде (, работает нормально ).

Пока все хорошо, но вот моя проблема :Чтобы форма была действительной, я должен добавить поля CSRF -к каждой WTForm. В шаблоне Jinja я делаю это с помощью:

{{ form.hidden_tag() }}

Однако, когда я просто копирую HTML с помощью моей функции js, я пропускаю поля CSRF -(, потому что до отправки объект внутренней формы не знает о добавленных FormFields ). Итак, как я могу динамически генерировать эти поля CSRF -? (Ajax-запрос? Если да, то как?)

Это должен быть стандартный вариант использования с формами и колбой. Я надеюсь, что мое описание было понятно, если нет, пожалуйста, дайте мне знать. Любая помощь приветствуется!

ОБНОВЛЕНИЕ :Вот мой код

JS -функции

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);
}

Шаблон Джиндзя:

<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 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 %}
10
задан kadrian 2 August 2012 в 13:26
поделиться