<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.
1.
<form action="/login" method="post">
2.
<form name="sentMessage" action="{{url_for('receive_data')}}"
method="post">
(URL) "where to" send the submitted form-data.
<form action="URL">
"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"])
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
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.
<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.@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)
Used boolean parameter for if statement.
(msg_sent = True/False)
Returns 'contact' template to get input data
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.