title: wtforms, CSRF, flask, FieldList
body: <p>I'm having trouble passing through validation when using a <code>FieldList</code> with WTForms.  I keep getting this error.  <code>{'csrf_token': [u'CSRF token missing']}</code>.  The problem is if I do not have any data to validate in the <code>FieldList</code> field, the validation passes and there are no issues.  But when I try to validate the form with any data I get that error.  </p>
  
  <p>Here are my forms:</p>
  
  <pre><code>class FilterForm(wtf.Form):
      filter_value = wtf.TextField('Value', validators=[validators.Required()])
      filter_operator = wtf.SelectField('Operator', validators=[validators.Required()])
      filter_compare_value=wtf.TextField('Compare Value', validators=[validators.Required()])
  
  
  class RedirectForm(wtf.Form):
      redirect_id = wtf.HiddenField('id')
      redirect_name = wtf.TextField('Name', validators=[validators.Required()])
      redirect_url = wtf.TextField('URL', validators=[validators.Required()])
      redirect_type = wtf.SelectField('Type', validators=[validators.Required()])
      redirect_method = wtf.SelectField('Method', validators=[validators.Required()])
      redirect_active = wtf.BooleanField('Is Active')
      redirect_filters_any = wtf.FieldList(wtf.FormField(FilterForm))
      redirect_filters_all = wtf.FieldList(wtf.FormField(FilterForm))
  </code></pre>
  
  <p>The form seems to display correctly and works fine until I add data to either <code>redirect_filters_any</code> or <code>redirect_filters_all</code></p>
  
  <p>Is there a way to disable csrf for the <code>FieldList</code> or pass a CSRF value to the <code>FieldList</code>? I want to keep CSRF protection enabled but can not seem to get past this validation problem.</p>
  
  <p>Here is the Jinja2 template</p>
  
  <pre><code>{% extends "base.html" %}
  {% set active_page = "endpoints" %}
  {% block tail_script %}
  &lt;script src="/static/js/page/redirects.js"&gt;&lt;/script&gt;
  {% endblock %}
  {% block content %}
  &lt;div class="row12"&gt;
      &lt;div class="span12"&gt;
          &lt;ul class="breadcrumb"&gt;
                &lt;li&gt;&lt;a href="{{ url_for('list_endpoints') }}"&gt;Endpoints&lt;/a&gt; &lt;span class="divider"&gt;/&lt;/span&gt;&lt;/li&gt;
                &lt;li&gt;&lt;a href="{{ url_for('show_endpoint', id=endpoint_id) }}"&gt;{{endpoint_name}}&lt;/a&gt; &lt;span class="divider"&gt;/&lt;/span&gt;&lt;/li&gt;
                {% if redirect_id != 'new' %}
                &lt;li class="active"&gt;{{ form.redirect_name.data }}&lt;/li&gt;
                {% else %}
                &lt;li class="active"&gt;New&lt;/li&gt;
                {% endif %}
          &lt;/ul&gt;
          &lt;form action="{{ url_for('edit_redirect', endpoint_id=endpoint_id, redirect_id=redirect_id) }}" class="form-horizontal" method="post"&gt;
              &lt;legend&gt;General&lt;/legend&gt;
              {{ form.hidden_tag() }}
              &lt;div class="control-group {% if form.redirect_name.errors %}error{% endif %}"&gt;
                  &lt;div class="control-label"&gt;{{ form.redirect_name.label }}&lt;/div&gt;
                  &lt;div class="controls"&gt;
                      {{ form.redirect_name|safe }}
                      {% if form.redirect_name.errors %}
                      &lt;span class="help-inline"&gt;
                           &lt;ul class="errors"&gt;
                              {% for error in form.redirect_name.errors %}
                              &lt;li&gt;{{ error }}&lt;/li&gt;
                              {% endfor %}
                          &lt;/ul&gt;
                      &lt;/span&gt;
                     {% endif %}
                  &lt;/div&gt;
              &lt;/div&gt;
              &lt;div class="control-group {% if form.redirect_type.errors %}error{% endif %}"&gt;
                  &lt;div class="control-label"&gt;{{ form.redirect_type.label }}&lt;/div&gt;
                  &lt;div class="controls"&gt;
                      {{ form.redirect_type|safe }}
                      {% if form.redirect_type.errors %}
                      &lt;span class="help-inline"&gt;
                           &lt;ul class="errors"&gt;
                              {% for error in form.redirect_type.errors %}
                              &lt;li&gt;{{ error }}&lt;/li&gt;
                              {% endfor %}
                          &lt;/ul&gt;
                      &lt;/span&gt;
                     {% endif %}
                  &lt;/div&gt;
              &lt;/div&gt;
              &lt;div class="control-group {% if form.redirect_active.errors %}error{% endif %}"&gt;
                  &lt;div class="control-label"&gt;{{ form.redirect_active.label }}&lt;/div&gt;
                  &lt;div class="controls"&gt;
                      {{ form.redirect_active|safe }}
                      {% if form.redirect_active.errors %}
                      &lt;span class="help-inline"&gt;
                           &lt;ul class="errors"&gt;
                              {% for error in form.redirect_active.errors %}
                              &lt;li&gt;{{ error }}&lt;/li&gt;
                              {% endfor %}
                          &lt;/ul&gt;
                      &lt;/span&gt;
                     {% endif %}
                  &lt;/div&gt;
              &lt;/div&gt;
              &lt;div class="control-group {% if form.redirect_method.errors %}error{% endif %}"&gt;
                  &lt;div class="control-label"&gt;{{ form.redirect_method.label }}&lt;/div&gt;
                  &lt;div class="controls"&gt;
                      {{ form.redirect_method|safe }}
                      {% if form.redirect_method.errors %}
                      &lt;span class="help-inline"&gt;
                           &lt;ul class="errors"&gt;
                              {% for error in form.redirect_method.errors %}
                              &lt;li&gt;{{ error }}&lt;/li&gt;
                              {% endfor %}
                          &lt;/ul&gt;
                      &lt;/span&gt;
                     {% endif %}
                  &lt;/div&gt;
              &lt;/div&gt;
              &lt;div class="control-group {% if form.redirect_url.errors %}error{% endif %}"&gt;
                  &lt;div class="control-label"&gt;{{ form.redirect_url.label }}&lt;/div&gt;
                  &lt;div class="controls"&gt;
                      {{ form.redirect_url|safe }}
                      {% if form.redirect_url.errors %}
                      &lt;span class="help-inline"&gt;
                           &lt;ul class="errors"&gt;
                              {% for error in form.redirect_url.errors %}
                              &lt;li&gt;{{ error }}&lt;/li&gt;
                              {% endfor %}
                          &lt;/ul&gt;
                      &lt;/span&gt;
                     {% endif %}
                  &lt;/div&gt;
              &lt;/div&gt;
              &lt;legend&gt;Meet All Filters &lt;a href="#" class="btn addAllFilter"&gt;Add&lt;/a&gt;&lt;/legend&gt;
              &lt;table class="stable-striped" id="all_filter_table"&gt;
                  &lt;tbody&gt;
              {% for f in form.redirect_filters_all %}
                  &lt;tr style="vertical-align:top;"&gt;
                      &lt;td&gt;    
                          {{ f.filter_value }}
                          {% if f.filter_value.errors %}
                          &lt;br&gt;
                          &lt;div class="control-group error"&gt;
                              &lt;span class="help-inline"&gt;
                                   &lt;ul class="errors"&gt;
                                      {% for error in f.filter_value.errors %}
                                      &lt;li&gt;{{ error }}&lt;/li&gt;
                                      {% endfor %}
                                  &lt;/ul&gt;
                              &lt;/span&gt;
                          &lt;/div&gt;
                          {% endif %}
                      &lt;/td&gt;
                      &lt;td&gt;    
                          {{ f.filter_operator }}
                          {% if f.filter_operator.errors %}
                          &lt;br&gt;
                          &lt;div class="control-group error"&gt;
                              &lt;span class="help-inline"&gt;
                                   &lt;ul class="errors"&gt;
                                      {% for error in f.filter_operator.errors %}
                                      &lt;li&gt;{{ error }}&lt;/li&gt;
                                      {% endfor %}
                                  &lt;/ul&gt;
                              &lt;/span&gt;
                          &lt;/div&gt;
                          {% endif %}
                      &lt;/td&gt;
                      &lt;td&gt;    
                          {{ f.filter_compare_value }}
                          {% if f.filter_compare_value.errors %}
                          &lt;br&gt;
                          &lt;div class="control-group error"&gt;
                              &lt;span class="help-inline"&gt;
                                   &lt;ul class="errors"&gt;
                                      {% for error in f.filter_compare_value.errors %}
                                      &lt;li&gt;{{ error }}&lt;/li&gt;
                                      {% endfor %}
                                  &lt;/ul&gt;
                              &lt;/span&gt;
                          &lt;/div&gt;
                          {% endif %}
                      &lt;/td&gt;
                      &lt;td&gt;&lt;a href="#" class="btn remove"&gt;Remove&lt;/a&gt;&lt;/td&gt;
                  &lt;/tr&gt;
              {% endfor %}
                  &lt;/tbody&gt;
              &lt;/table&gt;
              &lt;legend&gt;Meet Any Filters &lt;a href="#" class="btn addAnyFilter"&gt;Add&lt;/a&gt;&lt;/legend&gt;
              &lt;table class="stable-striped" id="any_filter_table"&gt;
                  &lt;tbody&gt;
              {% for f in form.redirect_filters_any %}
                  &lt;tr style="vertical-align:top;"&gt;
                      &lt;td&gt;    
                          {{ f.filter_value }}
                          {% if f.filter_value.errors %}
                          &lt;br&gt;
                          &lt;div class="control-group error"&gt;
                              &lt;span class="help-inline"&gt;
                                   &lt;ul class="errors"&gt;
                                      {% for error in f.filter_value.errors %}
                                      &lt;li&gt;{{ error }}&lt;/li&gt;
                                      {% endfor %}
                                  &lt;/ul&gt;
                              &lt;/span&gt;
                          &lt;/div&gt;
                          {% endif %}
                      &lt;/td&gt;
                      &lt;td&gt;    
                          {{ f.filter_operator }}
                          {% if f.filter_operator.errors %}
                          &lt;br&gt;
                          &lt;div class="control-group error"&gt;
                              &lt;span class="help-inline"&gt;
                                   &lt;ul class="errors"&gt;
                                      {% for error in f.filter_operator.errors %}
                                      &lt;li&gt;{{ error }}&lt;/li&gt;
                                      {% endfor %}
                                  &lt;/ul&gt;
                              &lt;/span&gt;
                          &lt;/div&gt;
                          {% endif %}
                      &lt;/td&gt;
                      &lt;td&gt;    
                          {{ f.filter_compare_value }}
                          {% if f.filter_compare_value.errors %}
                          &lt;br&gt;
                          &lt;div class="control-group error"&gt;
                              &lt;span class="help-inline"&gt;
                                   &lt;ul class="errors"&gt;
                                      {% for error in f.filter_compare_value.errors %}
                                      &lt;li&gt;{{ error }}&lt;/li&gt;
                                      {% endfor %}
                                  &lt;/ul&gt;
                              &lt;/span&gt;
                          &lt;/div&gt;
                          {% endif %}
                      &lt;/td&gt;
                      &lt;td&gt;&lt;a href="#" class="btn remove"&gt;Remove&lt;/a&gt;&lt;/td&gt;
                  &lt;/tr&gt;
              {% endfor %}
                  &lt;/tbody&gt;
              &lt;/table&gt;
              {% if g.user.user_type == 'admin' %}
              &lt;div class="control-group"&gt;
                  &lt;div class="controls"&gt;
                      &lt;input class="btn btn-primary" type="submit" value="Save"/&gt;
                      &lt;a href="{{url_for('show_endpoint', id=endpoint_id)}}" class="btn"&gt;Cancel&lt;/a&gt;
                  &lt;/div&gt;
              &lt;/div&gt;
              {% endif %}
          &lt;/form&gt;
      &lt;/div&gt;
  &lt;/div&gt;
  {% endblock %}
  </code></pre>