How to detect bugs on POST request(flask)?

347 Views Asked by At

I'm new to flask. I was trying to apply post/redirect/get pattern to my program. Here is what I did.

In the index.html

{% block page_content %}
<div class="container">
    <div class="page-header">
        <h1>Hello, {% if user %} {{ user }} {% else %} John Doe {% endif %}: {% if age %} {{ age }} {% else %} ?? {% endif %}</h1>
    </div>
</div>
    {% if form %}
    {{wtf.quick_form(form)}}
    {% endif %}
{% endblock %}

In the views.py

class NameForm(Form):
    age = DecimalField('What\'s your age?', validators=[Required()])
    submit = SubmitField('Submit')

''''''
@app.route('/user/<user>', methods=['GET', 'POST'])
def react(user):
    session['user'] = user
    form = NameForm()
    if form.validate_on_submit():
        old_age = session.get('age')
        if old_age != None and old_age != form.age.data:
            flash('age changed')
            session['age'] = form.age.data
        return redirect(url_for('react', user = user))
    return render_template('index.html', user = user, age = session.get('age'), form = form, current_time = datetime.utcnow())

The GET request is processed well when I open xxxx:5000/user/abc. However, the POST request fails. I get a 404 error. I think the url_for function may give a wrong value to redirect. How can I check the value returned by url_for?

I got a 405 error when I tried to use database. This time I have no clue.

@app.route('/search', methods=['GET', 'POST'])
def search():
    form = SearchForm() # a StringField to get 'name' and SubmitField
    if form.validate_on_submit():
        person = Person.query.filter_by(name = form.name.data) # Person table has two attributes 'name' and 'age'
        if person is None:
            flash('name not found in database')
        else:
            session['age'] = person.age
            return redirect(url_for('search'))
    return render_template('search.html', form = form, age = session.get('age'), current_time = datetime.utcnow())

Is there a convenient way to debug when the POST request fails?

1

There are 1 best solutions below

2
On BEST ANSWER

The problem isn't url_for(), it's the way you're using wtf.quick_form(). Take a look at the form generated by your code:

<form action="." method="post" class="form" role="form">

The action="." line tells the browser to take the information given and POST it to the URL .. The period (.) means "current directory." So what's happening is you're clicking submit, and then your browser POSTs to localhost:5000/users/. Flask sees this request to /users/ and cannot serve it, because /users/ isn't a valid URL. That's why you're getting a 404.

Fortunately, this can be fixed. In index.html, try calling quick_form() and passing in an action:

{{wtf.quick_form(form, action=url_for('react', user=user))}}

Now, your form is rendered like this:

<form action="/user/abc" method="post" class="form" role="form">

and your browser knows to POST the form to /user/abc, which is a valid URL, so Flask will handle it.

You didn't post your code for search.html, but try applying the same logic above to that template as well; hopefully that'll fix the issue!