0

When I settup two forms in one view with Flask_wtf, after a submit of one form which raise validations errors, all fields of the two forms display validations errors. How can I show only validations errors for the good form? (I am beginner with Python and Web Devellopment (and in English, sorry))

I've tried to set "prefix" attribut for each form and to hide validations errors on the other forms but i failed.

My forms classes :

class UpdateUserForm(FlaskForm):
    username = StringField("Utilisateur", validators=([DataRequired()]))
    picture = FileField("Photo de profil", validators=(
        [FileAllowed(['jpg', 'png'])]))
    submit = SubmitField("Mettre à jour")

    def validate_username(self, field):
        user = User.query.filter_by(username=field.data).first()
        if user and user.username != current_user.username:
            raise ValidationError(
                'Ce nom d\'utilisateur a déjà été enregistré !')


class UpdateUserPasswordForm(FlaskForm):
    password = PasswordField("Mot de passe", validators=([DataRequired(), EqualTo(
        'password_confirm', message='mots de passe non identiques !')]))
    password_confirm = PasswordField(
        "Confirmation du mot de passe", validators=([DataRequired()]))
    submit = SubmitField("Mettre à jour")

    def validate_password(self, field):
        schema = {'password': {'type': 'string',
                               'check_with': 'PasswordComplexity', 'minlength': 8}}
        v = CustomValidator(schema)
        document = {'password': field.data}
        if not v.validate(document):
            raise ValidationError(
                'Le mot de passe n\'est pas assez complexe (minimun 8 caractères, une majuscule, une minuscule, et un caractère spécial suivant !@#$.%^&*_- )')

My view :

@users.route('/account', methods=['GET', 'POST'])
@login_required
def account():
    #app.logger.info("--------------account()-------")
    form1 = UpdateUserForm(prefix='form1')
    form2 = UpdateUserPasswordForm(prefix='form2')

    if form1.validate_on_submit():
        if form1.picture.data:
            username = current_user.username
            pic = add_profile_pic(form1.picture.data, username)
            current_user.profile_image = pic

        current_user.username = form1.username.data

        db.session.commit()

        flash('Profil utilisateur modifié.')
        return redirect(url_for('users.account'))

    if form2.validate_on_submit():
        current_user.update_password(form2.password.data)
        db.session.commit()

        flash('Mot de passe modifié.')
        return redirect(url_for('users.account'))

    form1.username.data = current_user.username
    profile_image = url_for(
        'static', filename='profile_pics/'+current_user.profile_image)

    return render_template('users_account.html', profile_image=profile_image, form1=form1, form2=form2)

My HTML template :

<h5 class="card-header">Modification du profil</h5>
            <div class="card-body">
                <img src="{{ url_for('static', filename='profile_pics/'+current_user.profile_image) }}"
                    class="rounded mx-auto d-block" alt="image de profil">

                <form method="POST" enctype="multipart/form-data">
                    {{form1.hidden_tag()}}
                    <div class="form-group">
                        {{form1.username.label(class="form-control-label")}}
                        {{form1.username(class="form-control")}}
                        {% if form1.username.errors  %} 
                        <small class="form-text text-muted">
                            {% for error in form1.username.errors %}
                            {{ error }}
                            {% endfor %}
                        </small>
                        {% endif %}
                    </div>
                    <div class="form-group">
                        {{form1.picture.label(class="form-control-label")}}
                        {{form1.picture(class="btn btn-outline-secondary btn-sm")}}
                        {% if form1.picture.errors %} 
                        <small class="form-text text-muted">
                            {% for error in form1.picture.errors %}
                            {{ error }}
                            {% endfor %}
                        </small>
                        {% endif %}
                    </div>
                    {{form1.submit(class="btn btn-outline-primary")}}
                </form>

            </div>
        </div>
    </div>
    <div class="col">
        <div class="card mb-3">
            <h5 class="card-header">Modification du mot de passe</h5>
            <div class="card-body">

                <form method="POST">
                    {{form2.hidden_tag()}}
                    <div class="form-group">
                        {{form2.password.label(class="form-control-label")}}
                        {{form2.password(class="form-control")}}
                        {% if form2.password.errors %}
                        <small class="form-text text-muted">
                            {% for error in form2.password.errors %}
                            {{ error }}
                            {% endfor %}
                        </small>
                        {% endif %}
                    </div>
                    <div class="form-group">
                        {{form2.password_confirm.label(class="form-control-label")}}
                        {{form2.password_confirm(class="form-control")}}
                        {% if form2.password_confirm.errors %} 
                        <small class="form-text text-muted">
                            {% for error in form2.password_confirm.errors %}
                            {{ error }}
                            {% endfor %}
                        </small>
                        {% endif %}
                    </div>
                    {{form2.submit(class="btn btn-outline-primary")}}
                </form>

            </div>

I expect to show validations errors only for the good form not for the both.

Thank you

1 Answers1

0

Possible duplicate of this, with the answer https://stackoverflow.com/a/39766205/4967694

You need to specify in the view which form is being submitted when you do validation, for example:

if form1.submit.data and form1.validate_on_submit():
    ...
djnz
  • 2,021
  • 1
  • 13
  • 13