Flask by Example: Request Form Data
Handling HTML form submissions is a core task for web apps. Flask makes accessing POST data straightforward via the `request.form` object.
Code
from flask import Flask, request, render_template_string
app = Flask(__name__)
@app.route('/submit', methods=['GET', 'POST'])
def submit():
if request.method == 'POST':
# 1. Access form data
username = request.form.get('username')
password = request.form.get('password')
# 2. Validate
if not username or not password:
return "Missing fields", 400
# 3. Process data (e.g. login)
return f"Logged in as {username}"
# Render a simple form for GET requests
return '''
<form method="post">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<button type="submit">Login</button>
</form>
'''Explanation
When a browser submits a form with method="post", Flask parses the data into the request.form dictionary. This object behaves like a standard dictionary but is specialized for handling form data sent in the request body.
It is common to handle both displaying the form (GET) and processing it (POST) in the same view function. You can distinguish between these actions by checking request.method. This keeps the logic for a specific feature contained within a single function.
Always remember that data coming from the client is untrusted. Even with HTML required attributes, you must validate request.form data on the server side before using it in your application logic or database queries to prevent security vulnerabilities.
Code Breakdown
methods=['GET', 'POST']. By default, routes only answer to GET. You must explicitly allow POST requests if you want to handle form submissions.if request.method == 'POST':. This block handles the form submission. If the method is GET (the user just navigated to the page), this block is skipped and the HTML form is returned.request.form.get('username') retrieves the value of the input field with name="username". Using .get() prevents crashes if the field is missing.render_template to keep your logic separate from your presentation.
