TIL Python Basics Day 60 - Make POST Requests with Flask and HTML Forms

이다연·2021년 2월 17일
0

Udemy Python Course

목록 보기
56/64

HTML Forms in Flask

    <form>
        <label>Name</label>
        <input type="text" placeholder="name">
        <label>Password</label>
        <input type="password" placeholder="password">
        <button type="submit">Ok</button>
    </form>

(html)

  • 'type=password' provides a way for the user to securely enter a password
  • The name attribute inside html input element<input ~ name="username"> identifies the input data.


Action & Method at HTML Form

1.
<form action="/login" method="post">

2.
<form name="sentMessage" action="{{url_for('receive_data')}}" 
method="post">

Action:

(URL) "where to" send the submitted form-data.

<form action="URL"> 

Method:

"how" to send form-data (to the specified url page in the action attribute).

1. mehtod="get": (by default)
The form-data can be sent as URL variables
Never use GET to send sensitive data! (will be visible in the URL)

<form method="get"> 

2. method="post":
HTTP post transaction

<form method="post"> 

methods parameter accepts a dictionary, so you can have multiple methods targeted by one route.
e.g.

@app.route("/contact", methods=["GET", "POST"])

url_for()

Why use url_for() function rather than hardcoding?

  • You can change your URLs in one go instead of needing to remember to manually change hard-coded URLs.

NOTE: The action attribute of the form can be set to "/login" e.g.

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

or it can be dynamically generated with url_for e.g.

<form action="{‌{ url_for('receive_data') }}" method="post">

Depending on where your server is hosted, the "/login" path may change. So it's usually a better idea to use url_for to dynamically generate the url for a particular function in your Flask server.


@app.route('/')
def index():
    return 'index'

@app.route('/login')
def login():
    return 'login'

@app.route('/user/<username>')
def profile(username):
    return '{}\'s profile'.format(escape(username))

with app.test_request_context():
    print(url_for('index'))
    print(url_for('login'))
    print(url_for('login', next='/'))
    print(url_for('profile', username='John Doe'))

/
/login
/login?next=/
/user/John%20Doe #space -> %20

url Docs


Request Object (at server.py)

Get the form-data from html and get hold of it.

Allows us to tap into the parameters of the request that was made to our server.

Stackoverflow

  • The name attribute inside html input element<input ~ name="username"> identifies the input data.
  • request.form['username'] request is an object from Flask module. 'request.form' gives us the data the user entered in the form as a dictionary.
    -The name attribute from the 'input' is the key of dict.
@app.route("/login", methods=["POST"])
def receive_data():

    username = request.form['username']
    password = request.form['password']

    return render_template("login.html",
    username=username, password=password)

POST/GET & if statement

Used boolean parameter for if statement.
(msg_sent = True/False)

GET (before)

Returns 'contact' template to get input data

POST (after)

Gets hold of input form data from html form

main.py

@app.route("/contact", methods=["GET", "POST"])
def contact():

    if request.method == 'POST':
        data = request.form
        print(data["name"])
        print(data["email"])
        print(data["phone"])
        print(data["message"])
        return render_template("contact.html", msg_sent=True)
    else:
        return render_template("contact.html", msg_sent=False)

contact.html

  <div class="page-heading">
             {% if msg_sent: %}
            <h1>Successfully sent message!</h1>
             {% else: %}
            <h1>Contact Me</h1>
             {% endif %}

----------------------------
      
<form name="sentMessage" id="contactForm" action="{{url_for('contact')}}" method="post" novalidate>
          <div class="control-group">
            <div class="form-group floating-label-form-group controls">
              <label>Name</label>
              <input type="text" class="form-control" placeholder="Name" id="name" name="name" required data-validation-required-message="Please enter your name.">
              <p class="help-block text-danger"></p>
            </div>
          </div>

Final Result

Everything clicked now, however, I spent four hours on it. I felt it was not very time efficient. I considered skipping WTForms for Flask because I need to understand all the tedious details when It's not the main skill I need.
I changed my mindset though. Django, Flask are essentially similar as in it's a framework to build a website. Angela provides helpful instructions. I will learn both and it will broaden my understanding. Speed will increase as all the concepts like DB, Forms, authentication are the same topic in django as well.

profile
Dayeon Lee | Django & Python Web Developer

0개의 댓글