Колба-бутстрап с двумя формами на одной странице

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

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block page_content %}                                                   
<div class="page-header">                                                  
    <h1>Edit Profile</h1>
</div>

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

<hr>

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

<hr>
{% endblock %} 

Каждая форма имеет кнопку отправки.

В функции маршрута я попытался разделить две формы следующим образом

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:
    .....

Но это не сработало. Когда я нажимаю на кнопку в ResetForm, выполняется логика проверки ProfileForm.

Я подозреваю, что проблема в том, что wtf.quick_form() создает две одинаковые кнопки отправки, но не уверен.

Что мне делать в этом случае? Можно bootstrap/wtf.html шаблон справиться с этой ситуацией?

1 ответ

Решение

Определите эти два SubmitField с разными именами, например так:

class Form1(Form):
    name = StringField('name')
    submit1 = SubmitField('submit')

class Form2(Form):
    name = StringField('name')
    submit2 = SubmitField('submit')

Затем в view.py:

....
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 
....

Теперь проблема была решена.

Если вы хотите погрузиться в это, то продолжайте читать.

Вот validate_on_submit():

    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()

И вот is_submitted():

    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")

Когда вы звоните form.validate_on_submit(), он проверяет, была ли форма отправлена ​​методом HTTP, независимо от того, какая кнопка отправки была нажата. Итак, маленький трюк выше - просто добавьте фильтр (чтобы проверить, есть ли у данных данные, т.е. form1.submit1.data).

Кроме того, мы меняем порядок if, поэтому, когда мы нажимаем одну отправку, она вызывает только validate() для этой формы, предотвращая ошибку проверки для обеих форм.

История еще не закончена. Вот .data:

@property
def data(self):
    return dict((name, f.data) for name, f in iteritems(self._fields))

Он возвращает dict с именем поля (ключ) и данными поля (значение), однако наша кнопка отправки двух форм имеет одинаковое имяsubmit (ключ)!

Когда мы нажимаем первую кнопку отправки (в форме 1), звонок отform1.submit1.dataверните что-то вроде этого:

temp = {'submit': True}

Нет сомнений, когда мы звонимif form1.submit.data:, это возвращениеTrue,

Когда мы нажимаем вторую кнопку отправки (в форме 2), вызов .dataвif form1.submit.data:сначала добавьте ключ-значение в dict, затем вызов if form2.submit.data: добавьте еще одно значение ключа, в конце концов, dict будет выглядеть так:

temp = {'submit': False, 'submit': True}

Теперь мы называем if form1.submit.data:, это возвращение True, даже если кнопка отправки, которую мы нажали, была в форме2.

Вот почему мы должны определить эти два SubmitField с разными именами. Кстати, спасибо за чтение (здесь)!

Спасибо за уведомление nos, он добавляет вопрос о validate(), проверьте комментарии ниже!

Другие вопросы по тегам