5
votes

I am currently getting the following error when I run my flask code:

flask.debughelpers.FormDataRoutingRedirect - FormDataRoutingRedirect: A request was sent to this URL (http://localhost:5000/login) but a redirect was issued automatically by the routing system to "http://localhost:5000/login/". The URL was defined with a trailing slash so Flask will automatically redirect to the URL with the trailing slash if it was accessed without one. Make sure to directly send your POST-request to this URL since we can't make browsers or HTTP clients redirect with form data reliably or without user interaction.

I think it is to do with where the message flashing is placed but I can't seem to figure out how to fix this. I’m new to flask so not entirely sure what the best option is to solve this issue.

I have included my index.py and login.html file to help reproduce this error. Thanks in advance for the help! :)

Login section of app.py

@app.route('/login/', methods=['GET', 'POST'])
def login():
    form = LoginForm()

    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user:
            if check_password_hash(user.password, form.password.data):
                login_user(user, remember=form.remember.data)
                flash("Invalid username or password")
                return redirect(url_for('dashboard'))

    return render_template('login.html', form=form, errors=form.errors.items())

Login.html Template

{% block body_content %}
<div class="container">

<form method="POST" action="/login">
    {{ form.csrf_token }}
    <div class="form-group">
       {{ form.username }}
    </div>
    <div class="form-group">
        {{ form.password }}
    </div>
    <div class="form-group">
        {{ form.remember }}
    </div>
    <button type="submit" class="btn btn-primary">Sign In</button>
</form>

<div class="errors">
    {% for field, err in errors %}
        <p>{{field}} : {{err|join(', ')}}</p>
    {% endfor %}
</div>

<div class="message-flash">  
    {% for message in get_flashed_messages() %}
      <div class=flash>{{ message }}</div>
    {% endfor %}
</div> 

</div>
{% endblock %}
1

1 Answers

6
votes

Add a trailing slash to the action attribute inside the form as suggested in the message:

<form method="POST" action="/login/">

Preferably, use url_for to build URLs:

<form method="POST" action="{{ url_for('login') }}">

Since you're rendering the form with the same view that handles the post, you can omit the action.

<form method="POST">