urbainy
urbainy

Reputation: 77

Can not get data back from WTForms FormField on validate_on_submit

user_edit_profile.html:

{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block mainbody %}
    <div class="container">
        <div class="col-md-8 col-md-offset-2">
            <div class="page-header">
                <h3>{{ _('User Edit Profile') }}</h3>
            </div>
            <div>
                {{ wtf.quick_form(form, form_type="horizontal", horizontal_columns=('md', 3, 9)) }}
            </div>
        </div>
    </div>
{% endblock %}

forms.py

from flask_wtf import FlaskForm
from wtforms import Form
class UserBasicInfoForm(Form):
    surname = StringField(lazy_gettext("Surname"), validators=[Length(0, 64)])

class UserEditProfileForm(FlaskForm):
    basic_information = FormField(UserBasicInfoForm)
    submit = SubmitField(lazy_gettext("Submit"), id="user_edit_profile_submit")

user.py

@user.route("/edit-profile", methods=["GET", "POST"])
@login_required
def edit_profile():
    form = UserEditProfileForm()
    form.basic_information.surname.data = current_user.surname
    if form.validate_on_submit():
        current_user.surname = form.basic_information.surname.data
        print(form.basic_information.surname.data)
        current_user.save()
        return redirect(url_for("frontend.index"))
    return render_template("user_edit_profile.html", form=form)

I didn't paste the models.py since it works well, I think there is no problem.

Now, print(form.basic_information.surname.data) feedbacks None, which means I cannot get anything from the input in the surname field in the wtf form.

When I use Charles to capture the packet, I found the client really had sent the input thing, such as "Smith" to the server. But obviously the server lost it.

I also tried to use FlaskForm instead of Form in the subform at the same time I override the csrf_enabled args to False by using:

def __init__(self, *args, **kwargs):
    kwargs['csrf_enabled'] = False
    FlaskForm.__init__(self, *args, **kwargs)

But this didn't help.

I don't know where is the problem, thanks for your help!

Upvotes: 1

Views: 1090

Answers (1)

Grey Li
Grey Li

Reputation: 12772

The cause of this problem was order, in the beginning, your current_user.surname is None, you write this:

form.basic_information.surname.data = current_user.surname

So your form.basic_information.surname.data is None, at the same time, the form data form.basic_information.surname.data was covered.

The correct order is like this:

@user.route("/edit-profile", methods=["GET", "POST"])
@login_required
def edit_profile():
    form = UserEditProfileForm()
    if form.validate_on_submit():
        # first!
        current_user.surname = form.basic_information.surname.data
        print(form.basic_information.surname.data)
        current_user.save()
        return redirect(url_for("frontend.index"))
    # second!
    form.basic_information.surname.data = current_user.surname
    return render_template("user_edit_profile.html", form=form)

Upvotes: 1

Related Questions