semisight
semisight

Reputation: 964

Flask receiving empty forms

I'm trying to get a simple form set up in Flask for my own education. I've got a login.html page with this form code:

<form action="{{ url_for('login') }}" method="post">
    <div>
        <label for="username">Username</label>
        <div>
            <input type="text" id="username" name="username" placeholder="Username">
        </div>
    </div>
    <div>
        <label for="password">Password</label>
        <div>
            <input type="password" id="password" name="password" placeholder="Password">
        </div>
    </div>
    <div >
        <input class="btn" type="submit">
    </div>
</form>

I'm using code like the following to receive it, but Flask returns an empty request.form so I can't process it.

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        request.form['username']
        ...

I really don't want to learn another library (WTForms) right now, and I'm using bootstrap so that will add to the headache. What am I not seeing here with Flask/HTML?

Upvotes: 31

Views: 29278

Answers (4)

DanteDX
DanteDX

Reputation: 1259

just use request.get_json() in POST requests

Upvotes: 0

I had that problem. Some tools like postman or some libraries or web browser sends the data in a way that flask does not identify as posted values. From my point of view this is a flask issue.

This is the workaround I followed to solve it: 1 - I sent the information using json. Have a look to this:

How to send a JSON object using html form data

2 - I instead of getting the parameters using: value = request.form["myparamname"] I used this:

json_data = request.get_json(force=True) 

value = json_data["myparamname"]

Upvotes: 18

Resonance
Resonance

Reputation: 3786

I had this problem, but it was because I forgot to assign a name attribute to my input elements and I was trying to refer access the form data by the id attribute instead

i.e.

My HTML and Python was as shown below

HTML

<input type="text" id="usernameTxtBx">

Python

request.form['usernameTxtBx']

What I have done now:

HTML

<input type="text" name="username" id="usernameTxtBx">

Python

request.form['username']

I also needed to ensure that I was using a POST request. A GET request gave me an empty dictionary in my python code.

The OP made neither of these mistakes. But this may help someone that stumbles on this thread.

Upvotes: 42

ajknzhol
ajknzhol

Reputation: 6450

login.html

{% extends "layout.html" %}

{% block content %}
  <div class="form">
    <h2>Sign In</h2>

 {% for field in form.errors %}
{% for error in form.errors[field] %}
    <div class="alert alert-error">
        <strong>Oops...</strong> {{error}}.
    </div>
{% endfor %}
{% endfor %}

  <form action="{{ url_for('login') }}" method=post>
    {{ form.hidden_tag() }}

    {{ form.email.label }}
    {{ form.email }}

    {{ form.password.label }}
    {{ form.password }}

      <p> <input id="submit" name="submit" type="submit" class="btn btn-inverse" value="Sign In"></p>
  </form>
</div>
{% endblock %}

forms.py

  class SigninForm(Form):
        email = TextField("email", [validators.Required("Please enter your email")])
        password = PasswordField('Password', [validators.Required("Please enter a password.")])
        submit = SubmitField("Sign In")

Then import the signinform in your views and create your login method like this

@app.route('/login', methods=['GET', 'POST'])
def signin():
  form = SigninForm()
  if form.validate_on_submit():
      session['email'] = form.email.data

      flash('You are logged in')
      return redirect(url_for('dashboard'))
  return render_template('signin.html', form=form)

Refer this tutorial for more detailed instructions http://pypix.com/python/building-flask-blog-part-1/

Upvotes: -3

Related Questions