Flask Routing Basics
# CHAPTER 5
Flask Routing Basics
1. Introduction
In the previous chapter, we mapped a single URL (/) to a specific Python function. But a real web application is a massive web of interconnected pages. How do you handle a blog with 5,000 articles? You certainly cannot write 5,000 separate @app.route decorators. In this chapter, we will master Routing. We will learn how to create multiple static routes, capture dynamic data from the URL (like a user's ID), and restrict routes to specific HTTP methods (GET vs. POST).
2. Learning Objectives
By the end of this chapter, you will be able to:- Define multiple static routes within a single application.
- Create dynamic routes that capture variables from the URL.
-
Use type converters (
<int:id>) to validate URL parameters.
-
Restrict routes to specific HTTP methods using
methods=['GET', 'POST'].
3. Beginner-Friendly Explanation
Imagine working at the post office sorting facility.-
Static Routing: A letter arrives addressed to "The Mayor." You know exactly which bin to put it in because there is only one Mayor. (
@app.route('/about')).
-
Dynamic Routing: A letter arrives addressed to "Citizen #402". You don't have a specific bin for every single citizen. Instead, you have a general "Citizens" conveyor belt. You pull the number "402" off the envelope and hand it to the delivery driver, saying, "Take this to whoever is number 402." (
@app.route('/user/<id>')).
Dynamic routing allows one single Python function to handle millions of different URLs automatically.
4. Step 1: Multiple Static Routes
Let's expand ourapp.py to handle standard website pages.
*You can define as many static routes as you want. Flask reads the URL and triggers the matching function.*
5. Step 2: Dynamic Routes (Capturing Variables)
If we want to display a user's profile, we use angle brackets< > in the route to capture the data and pass it into the function as an argument.
*Test it! Visit http://127.0.0.1:5000/profile/alice. The browser prints "Welcome to your profile, alice!" Visit /profile/bob, and it prints "bob". One function handles infinite URLs.*
6. Step 3: URL Type Converters
By default, dynamic routes capture data as strings. What if you are looking up a product by its ID number? If a user types/product/hello, your database will crash when it searches for an ID of "hello".
We can force Flask to only accept integers using a type converter.
*If a user visits /post/5, it works perfectly. If they visit /post/apple, Flask automatically blocks it and returns a 404 Not Found error!*
Common Converters:
-
<string:name>(Default) Accepts any text without a slash.
-
<int:id>Accepts positive integers.
-
<float:price>Accepts positive floating point values.
7. Step 4: HTTP Methods (GET vs POST)
By default, every@app.route only responds to GET requests (when a user types a URL into their browser).
If a user tries to submit an HTML form (a POST request) to that URL, Flask will reject it with a "405 Method Not Allowed" error. We must explicitly tell Flask to accept POST requests.
*(We will learn how to extract the actual form data in Chapter 7).*
8. Backend Workflow: Trailing Slashes
Pay close attention to trailing slashes in your routes.-
@app.route('/about')(No trailing slash): If a user visits/about/(with a slash), Flask returns a 404 error.
-
@app.route('/about/')(With trailing slash): If a user visits/about(no slash), Flask magically redirects them to/about/.
*Best Practice: Always include the trailing slash for major pages (/projects/) so users don't encounter 404 errors if they type it in manually.*
9. Best Practices
-
Route Naming Conventions: The name of your Python function (e.g.,
def show_post():) should be clear and unique. This function name is internally registered as the "Endpoint Name." Later, we will use this Endpoint Name to dynamically generate links in our HTML, preventing broken links if URL paths change.
10. Common Mistakes
- Function Name Collisions: A very common beginner mistake is writing two different routes but accidentally giving the Python functions the exact same name.
*Flask will crash with an AssertionError. Every View function must have a unique name.*
11. Exercises
-
1.
Trace the Request flow: A user types
http://127.0.0.1:5000/product/99. Explain chronologically how the number 99 is extracted from the URL and passed into the Python logic.
12. Coding Challenges
-
Challenge: In
app.py, write a new dynamic route:/calculator/<int:num1>/<int:num2>. The View function should accept both numbers as arguments, add them together, and return a string displaying the result (e.g., "The sum is 10"). Test it in your browser.
13. MCQs with Answers
What is the syntax used in a Flask route decorator to capture a dynamic section of the URL and enforce that it must be a whole number?
By default, a Flask route created with @app.route('/submit') will only respond to which HTTP method?
14. Interview Questions
- Q: Explain the concept of URL Type Converters in Flask. How do they act as a first layer of security and input validation before the data ever reaches the controller logic?
-
Q: Contrast a GET request with a POST request. In a web application, provide a specific scenario where you would explicitly configure a Flask route using
methods=['POST'].
15. FAQs
Q: Can I make a dynamic route optional? A: Yes! You can stack decorators on top of a single function and provide a default argument.16. Summary
In Chapter 5, we mastered Flask's routing engine. We scaled our application from a single page to a multi-page site by defining multiple static routes. We learned how to capture dynamic URL parameters using angle brackets (< >) and enforced data integrity using type converters like int. Finally, we introduced the concept of HTTP methods, preparing our routes to handle form submissions securely.