URLs are important for web applications. They are like an API for your application and search engines can use them to rank your site. Flask gives you a lot of flexibility to map URLs to your view functions.
This post is part of my journey to learn Python. You can find the other parts of this series here.
Routing?
In the post about Jinja templates I created a view function called tasks() that is mapped to the URL http://127.0.0.1:5000/tasks. The magic of mapping my function to that URL is called routing.
Flask needs to know only the part after the domain or IP address. This URL rule, as it is called, must be unique and map to only one view function. Flask uses the decorator pattern of Python to create this mapping as you can see in the first line of this example:
1 2 3 4 |
@app.route('/tasks') def tasks(): my_tasks = get_latest_tasks() return render_template('tasks.html', name='Johnny', tasks=my_tasks) |
Whenever someone asks for /tasks
in your application, Flask looks at the routing table, checks if a /tasks
rule exists and if so, runs the associated view function.
Static routes
Even in a dynamic web application you have a few pages that should return the same data for all users, for example the about page. For those pages you can use a static route like this one:
1 2 3 |
@app.route('/about') def about(): return render_template('about.html') |
The /about
route is called static because there are no dynamic parts in the URL rule. You cannot modify the content on the page by changing parameters in the URL.
Dynamic routes
A dynamic route is one in which we can modify the content of a site through the URL. We can create a hello world site that accepts the name to greet as part of the URL. All we need to do is to put the dynamic part of the URL rule between <> and create a parameter in our function with the same name:
1 2 3 |
@app.route('/hello/<name>') def hello(name): return render_template('hello.html', who=name) |
If I call my application with the URL /hello/Johnny
, I get this result:
If I change the URL to /hello/London
I get a different result:
This dynamic route lets my page change depending on a parameter in the URL. Online shops, newspapers, and everyone else use this concept to have many sites with different content without creating a view function and a template for each site.
This dynamic part is not optional. If you do not have a value for the placeholder name, you will get an error:
Type specific dynamic routes
Flask lets you limit your dynamic routes to a specific type. If you only want to allow numbers, you can add int: in front of your variable name:
1 2 3 |
@app.route('/even/<int:num>') def even_or_odd(num): return render_template('number.html', number=num) |
If I call my application with the URL /even/1
, I get this result:
However, if I enter /even/Johnny
I only get a page not found error:
Limit routes to specific HTTP methods
By default, Flask only accepts GET requests on your URLs. If you want to create a form and submit it, you will need to allow the POST method. You can allow other HTTP methods in the methods
argument of the route()
decorator:
1 2 3 4 |
@app.route('/send', methods=['POST']) def send(): data = request.form return data |
This method now only allows POST methods. We can use HTTPie to test if everything works:
1 2 3 4 5 6 7 8 9 10 |
$ http -f POST http://127.0.0.1:5000/send hello=World HTTP/1.0 200 OK Content-Length: 23 Content-Type: application/json Date: Fri, 04 Sep 2020 19:33:25 GMT Server: Werkzeug/1.0.1 Python/3.8.1 { "hello": "World" } |
When we go to /send in the browser (and do a GET request), we will get a method not allowed error:
Next
Flask gives us a lot of flexibility when it comes to routing. All we need to do is to call a decorator and it works. But how is this possible? And can we create decorators on our own? Let’s find out next week.
Great Article it its really informative and innovative keep us posted with new updates. its was really valuable. thanks a lot.