validate_on_submit (колба-wtf) не работает

#flask #flask-wtforms #werkzeug

Вопрос:

Я работаю над страницей регистрации. Проблема в том, что даже если я отправлю new_user данные, они не будут храниться в new_user базе данных и users/signup.html вместо этого будут возвращены. Я считаю, что validate_on_submit каким-то образом вызывает здесь проблему. Как я могу new_user правильно хранить данные?

users_bp.py

 from flask import Blueprint
from flask_login import login_user, logout_user, current_user
from flask import redirect, render_template, request, flash
from flask import url_for
from flask_login import LoginManager
from werkzeug.security import generate_password_hash, check_password_hash

@login_manager.user_loader
def user_loader(user_id):
    return User.query.get(int(user_id))


@user.route('/signup', methods=['GET', 'POST'])
def signup():
    form = SignupForm()

    if form.validate_on_submit():
        nickname = form.nickname.data
        email = form.email.data
        password = form.password.data

        user = User.query.filter_by(email=email).first()

        if user:
            return render_template('users/login.html')

        new_user = User(email=email, nickname=nickname,
                        password=generate_password_hash('password', method='sha256'))

        db.session.add(new_user)
        db.session.commit()
        return render_template('home.html')
    return render_template('users/signup.html', form=form)
 

user_form.py

 from flask.app import Flask
from flask.templating import render_template
from wtforms import TextAreaField, StringField, Form, SelectField, SubmitField, PasswordField, DateField
from flask_wtf import FlaskForm
from wtforms.validators import DataRequired
from werkzeug.utils import redirect

class SignupForm(FlaskForm):
    nickname = StringField('nickname')
    email = StringField('email', validators=[DataRequired(), Email()])
    password = PasswordField('password', validators=[DataRequired()])
    recaption = RecaptchaField()
    send = SubmitField('submit')
 

users/signup.html

 {% block content %}
<div class="info-container">
    <div class="column is-4 is-offset-4">
        <h2 class="title">新規登録</h2>
        <div class="sign-description login-description">アカウントをお持ちの方はこちらから<a
                href="{{url_for('user.login')}}">ログイン</a>してください
        </div>
    </div>
</div>
<form action="" id="SignupForm" method="POST">
    {{ form.hidden_tag() }}
    <div class="form-group m-5">
        {{ form.nickname.label() }}
        {{ form.nickname(class='form-control') }}
        {% if form.nickname.errors %}
        <ul class="errors">
            {% for error in form.nickname.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}
    </div>
    <div class="form-group m-5">
        {{ form.email.label() }}
        {{ form.email(class='form-control') }}
        {% if form.email.errors %}
        <ul class="errors">
            {% for error in form.email.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}
    </div>
    <div class="form-group m-5">
        {{ form.password.label() }}
        {{ form.password(class='form-control') }}
        {% if form.password.errors %}
        <ul class="errors">
            {% for error in form.password.errors %}
            <li>{{ error }}</li>
            {% endfor %}
        </ul>
        {% endif %}
    </div>
    {{ form.send(class='btn btn-outline-dark mb-5 form-control') }}
</form>

{% endblock %}
 

Комментарии:

1. Вполне возможно, что validate_on_submit это не удастся. Используйте form.errors , чтобы узнать, есть ли ошибки при отправке вашей формы. И, возможно, добавьте свой шаблон формы к вашему вопросу. Вы можете просто добавить: {{ form.errors }} на своей странице signup.html.

2. Привет @Anonymous. Спасибо вам за предложение! Я добавил: users/signup.html».

Ответ №1:

Одно предположение: проблема может заключаться в отсутствующей капче, которая определена в вашей модели формы. Если какое-либо из требований в вашем классе формы не выполнено, это validate_on_submit должно привести к сбою. Но вы не справляетесь с этим условием.

Используйте form.errors для выплевывания ошибок проверки, если таковые имеются…

Я предполагаю, что вы используете Bootstrap, лично я использую что-то подобное в своих шаблонах форм:

 {% if form.is_submitted() and form.errors|count > 0 %}
<div class="alert alert-danger alert-dismissible fade show" role="alert">
    {{ form.errors|count }} error(s):
    <ul>
    {% for field_name, field_errors in form.errors|dictsort if field_errors %}
        {% for error in field_errors %}
            <li>{{ form[field_name].label }}: {{ error }}</li>
        {% endfor %}
    {% endfor %}
    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endif %}
 

При этом появится красное поле с перечнем ошибок формы (если таковые имеются).

Если форма не проходит проверку, вам нужно как-то сообщить об этом пользователю.