Как перенаправить, сохраняя данные формы, используя Flask и WTForms? - PullRequest
1 голос
/ 05 июля 2019

Давайте создадим страницу с регистрационной формой.Это в разделе #registration.Если пользователь отправляет недействительные данные, страница должна вернуть его обратно в раздел #registration и отобразить, в какие поля были переданы недопустимые значения.

Я попытался отобразить шаблон и сделать ответ и перенаправить на него, но яполучение TypeError:

  File ".../app/routes.py", line 28, in index
    return redirect(url_for('.index', form=form, _anchor='registration'), 302, response)
  File ".../python3.7/site-packages/werkzeug/utils.py", line 507, in redirect
    mimetype="text/html",
TypeError: __call__() got an unexpected keyword argument 'mimetype'

Функция выглядит следующим образом:

@app.route('/', methods=['GET', 'POST'])
def index():
    form = RegisterForm()
    if form.validate_on_submit():
        # everithing OK
        return redirect(url_for('.index', _anchor='registration'))

    # If form was submitted but contained invalid information
    if form.is_submitted():
        response = make_response(render_template('index.html', form=form))
        return redirect(url_for('.index', _anchor='registration'), 302, response)

    return render_template('index.html', form=form)

1 Ответ

1 голос
/ 05 июля 2019

Вы не можете отправлять контент с ответом redirect, вы можете только сказать "перейти по этому URL" .Кроме того, flask принимает класс Response, а не экземпляр в качестве параметра для redirect.

Чтобы решить вашу проблему, вам нужно использовать session (или просто flash ing) для сохранения состояния между запросами.

Вот прототип:

from flask import Flask, render_template_string, request, session, redirect
from werkzeug import MultiDict

from flask_wtf import FlaskForm
from wtforms import StringField, IntegerField
from wtforms.validators import AnyOf

app = Flask(__name__)
app.secret_key = 'secret'

class MyForm(FlaskForm):
    name = StringField('name', validators=[AnyOf(['secretname'])])

@app.route('/', methods=['POST', 'GET'])
def form():
    form = MyForm()
    html = '''
    {% for error in form.name.errors %} <span>{{ error }}</span> {% endfor %}
    <form method="POST" action="/">
        {{ form.csrf_token }}
        {{ form.name.label }} {{ form.name(size=20) }}
        <input type="submit" value="Go">
    </form>
    '''

    if request.method == 'GET':
        formdata = session.get('formdata', None)
        if formdata:
            form = MyForm(MultiDict(formdata))
            form.validate()
            session.pop('formdata')
        return render_template_string(html, form=form)

    if form.validate_on_submit():
        # use the form somehow
        # ...
        return redirect('/#registered')

    if form.is_submitted() and not form.validate():
        session['formdata'] = request.form
        return redirect('/#invalid')

if __name__ == "__main__":
    app.run()

Когда вы запускаете сервер, вы получаете:
enter image description here

После того, как вы отправите неверную форму, вы будете перенаправлены на /#invalid, и форма будет заполнена как выожидаемое ожидание:

invalid submission

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...