Handling Forms and User Input
# CHAPTER 7
Handling Forms and User Input
1. Introduction
A website without user input is just a digital brochure. Real applications require users to log in, submit comments, and upload data. In web development, this is achieved using HTML Forms. However, taking data from an HTML<form> and securely passing it into Python logic requires understanding how HTTP requests transport data. In this chapter, we will learn how to extract data from the request object, handle GET vs. POST methods elegantly, and securely process user input.
2. Learning Objectives
By the end of this chapter, you will be able to:-
Create an HTML form with the correct
actionandmethodattributes.
-
Import and utilize the global
requestobject in Flask.
-
Differentiate between
request.args(GET) andrequest.form(POST).
- Process form submissions within a View function.
-
Use
redirectto prevent duplicate form submissions.
3. Beginner-Friendly Explanation
Imagine a drive-thru window.- GET Request: You pull up and say, "Give me the menu." The cashier hands you the blank menu (The HTML Form).
- POST Request: You fill out the menu with your order, attach your credit card, and hand it back through the window.
In Flask, ONE single window (The View Function) has to handle both interactions. When a car pulls up, the cashier (Python) must ask, "Are you here to GET a blank menu, or are you here to POST a finished order?" Based on the answer, the cashier performs a completely different action.
4. Step 1: Building the HTML Form
Let's build a simple login form. Createtemplates/login.html:
5. Step 2: The View Function (GET vs POST)
Now we must configure the route to handle the form. We must explicitly allow thePOST method, and we must import the global request object to intercept the incoming data.
In app.py:
6. Step 3: The Redirect Pattern (PRG)
In Step 2, if the login is successful, we returned a string:return f"Welcome...".
This is a terrible practice. If the user refreshes the page, the browser will ask, "Are you sure you want to resubmit the form?" and they might accidentally buy an item twice!
This is solved by the Post/Redirect/Get (PRG) pattern. After a successful POST, you should ALWAYS redirect the user to a different GET page.
Updating the logic:
7. Step 4: Extracting GET Data (Query Strings)
Sometimes forms use theGET method (like search bars). When you search Google, the URL looks like this: /search?q=flask&sort=newest. The data is attached to the URL, not hidden in the request body.
To extract data from the URL, we use request.args instead of request.form.
8. Backend Workflow: WTForms (Advanced Forms)
Extracting data manually withrequest.form.get() is fine for tiny projects. However, it lacks validation. What if the user types letters into an "Age" field? What if they leave the email field blank?
In professional Flask apps, developers use a popular extension called Flask-WTF. It allows you to define forms as Python Classes, automatically generates the HTML, and handles complex validation (like verifying email formats) securely on the backend. We will cover this advanced extension in Chapter 15.
9. Best Practices
-
Use
.get()Instead of Dictionary Keys: Always userequest.form.get('email')instead ofrequest.form['email']. If the HTML form is broken and the 'email' field is missing, using dictionary brackets['email']will crash the entire server with aKeyError. Using.get()will safely returnNonewithout crashing.
10. Common Mistakes
-
Forgetting
methods=['GET', 'POST']: The #1 mistake beginners make is writing the HTML<form method="POST">, clicking submit, and seeing a "Method Not Allowed" error. By default, Flask routes only accept GET. You must explicitly add themethodslist to the decorator.
11. Exercises
-
1.
Explain the Post/Redirect/Get (PRG) pattern. Why is it dangerous to simply
rendertemplateafter successfully processing a POST request (like a credit card charge)?
12. Coding Challenges
-
Challenge: Create a newsletter signup form. Create an HTML file with an input field named
email. Inapp.py, map it to/subscribeaccepting GET and POST. If POST, extract the email and return a string thanking them. If GET, display the form.
13. MCQs with Answers
In Flask, which property of the global request object contains the data submitted via an HTML form using the POST method?
When creating a search bar that appends the search term directly into the URL (e.g., ?search=shoes), which HTTP method should the HTML form use?
14. Interview Questions
-
Q: Contrast
request.argsandrequest.formin Flask. Under what HTTP circumstances would you use each?
-
Q: Explain why sensitive data (like passwords) must NEVER be transmitted using an HTML form configured with
method="GET".
15. FAQs
Q: Can I handle the GET and POST logic in two separate functions instead of one bigif/else block?
A: Yes! It is perfectly valid to write @app.route('/login', methods=['GET']) on one function to show the form, and @app.route('/login', methods=['POST']) on a completely separate function to process the data.
16. Summary
In Chapter 7, we achieved bi-directional communication. We built HTML forms and learned the critical distinction between GET and POST methods. By importing Flask's globalrequest object, we successfully extracted hidden form data (request.form) and URL query parameters (request.args). Finally, we implemented the industry-standard Post/Redirect/Get (PRG) pattern to ensure safe, duplicate-free form submissions.