flask-bootstrap with two forms in one page
<p>I plan to put two forms in one page in my flask app, one to edit general user information and the other to reset password. The template looks like this</p>

<pre><code>{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block page_content %}                                                   
&lt;div class="page-header"&gt;                                                  
    &lt;h1&gt;Edit Profile&lt;/h1&gt;
&lt;/div&gt;

{{ wtf.quick_form(form_profile, form_type='horizontal') }}                 

&lt;hr&gt;

{{ wtf.quick_form(form_reset, form_type='horizontal') }}                   

&lt;hr&gt;
{% endblock %} 
</code></pre>

<p>Each form has a submit button. </p>

<p>In the route function, I tried to separate the two form like this</p>

<pre><code>form_profile = ProfileForm()
form_reset = ResetForm()

if form_profile.validate_on_submit() and form_profile.submit.data:
    ....
if form_reset.validate_on_submit() and form_reset.submit.data:
    .....
</code></pre>

<p>But it didn't work. When I click on the button in the ResetForm, the ProfileForm validation logic is executed. </p>

<p>I suspect the problem is that <code>wtf.quick_form()</code> creates two identical submit buttons, but not sure. </p>

<p>What should I do in this case? Can <code>bootstrap/wtf.html</code> template deal with this situation?</p>

<p>Define this two SubmitField with different names, like this:</p>

<pre><code>class Form1(Form):
    name = StringField('name')
    submit1 = SubmitField('submit')

class Form2(Form):
    name = StringField('name')
    submit2 = SubmitField('submit')
</code></pre>

<p>Then in <code>view.py</code>:</p>

<pre><code>....
form1 = Form1()
form2 = Form2()

if form1.submit1.data and form1.validate_on_submit():  # notice the order 
....
if form2.submit2.data and form2.validate_on_submit():  # notice the order 
....
</code></pre>

<p><strong>Now the problem was solved.</strong> </p>

<p>If you want to dive into it, then continue read.</p>

<p>Here is <code>validate_on_submit()</code>:</p>

<pre><code>    def validate_on_submit(self):
        """
        Checks if form has been submitted and if so runs validate. This is
        a shortcut, equivalent to ``form.is_submitted() and form.validate()``
        """
        return self.is_submitted() and self.validate()
</code></pre>

<p>And here is <code>is_submitted()</code>:</p>

<pre><code>    def is_submitted(self):
        """
        Checks if form has been submitted. The default case is if the HTTP
        method is **PUT** or **POST**.
        """

        return request and request.method in ("PUT", "POST")
</code></pre>

<p>When you call <code>form.validate_on_submit()</code>, it check if form has been submitted by the HTTP method no matter which submit button was clicked. So the little trick above is just add a filter (to check if submit has data, i.e., <code>form1.submit1.data</code>).</p>

<p>Besides, we change the order of if, so when we click one submit, <strong>it only call validate() to this form</strong>, preventing the validation error for both form.</p>

<p>The story isn't over yet. Here is <code>.data</code>:</p>

<pre><code>@property
def data(self):
    return dict((name, f.data) for name, f in iteritems(self._fields))
</code></pre>

<p>It return a dict with field name(key) and field data(value), however, <strong>our two form submit button has same name <code>submit</code>(key)!</strong> </p>

<p>When we click the first submit button(in form1), the call from <code>form1.submit1.data</code> return a dict like this:</p>

<pre><code>temp = {'submit': True}
</code></pre>

<p>There is no doubt when we call <code>if form1.submit.data:</code>, it return <code>True</code>.</p>

<p>When we click the second submit button(in form2), the call to <code>.data</code> in <code>if form1.submit.data:</code> add a key-value in dict <strong>first</strong>, then the call from <code>if form2.submit.data:</code> add another key-value, in the end, the dict will like this:</p>

<pre><code>temp = {'submit': False, 'submit': True}
</code></pre>

<p>Now we call <code>if form1.submit.data:</code>, it return <code>True</code>, even if the submit button we clicked was in form2. </p>

<p>That's why we need to define this two <code>SubmitField</code> with different names. By the way, thanks for reading(to here)!</p>

<p>Thanks for nos's notice, he add an issue about <code>validate()</code>, check the comments below!</p>

python flask flask-wtforms flask-bootstrap