Servers and Flask Web Applications
Create dynamic server-side apps with Flask, templates, and databases.
Content
Routing and Views
Versions:
Watch & Learn
AI-discovered learning video
Sign in to watch the learning video for this topic.
Flask Routing and Views — CS50 Edition: Routes, Views, and the Little Things That Make the Web Work
"Routing is just maps and directions for the internet — but the internet has trust issues and needs polite escorts called views."
You already set up your project and virtual environment (remember: venv love), learned about HTTP and REST basics, and built accessible, responsive pages with HTML/CSS/JS. Now let's glue the client and server together: how Flask receives requests (routing) and how it prepares responses (views/templates) so your browser and server can have a civil conversation.
What this lesson covers and why it matters
- What routing and view functions are in Flask, and how they map HTTP requests to Python code.
- How to handle URL parameters, GET vs POST, and forms. (Tie-in: HTTP methods from REST Basics.)
- How to render templates with Jinja2 and pass data from server to client (tie-in: your HTML/CSS/JS skills).
- Practical tips:
url_for,redirect,abort, and safe template rendering.
Why care? Because without routes and views, your server is a polite but empty house. Routes open the door; views welcome guests and hand them content (HTML, JSON, redirects, files). This is how user actions become server behavior.
1) Route basics — the URL -> function mapping
A Flask route connects a URL pattern to a Python function (a view function). Think of a route like a mailbox label: when a request arrives for /profile, Flask looks up the mailbox and runs the function attached.
Example minimal app:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello, world!'
if __name__ == '__main__':
app.run(debug=True)
Notes:
@app.route('/')declares the route. The decorated function returns the response.app.run(debug=True)starts the dev server with auto-reload (handy while iterating during development — you set this up in your venv earlier!).
Micro explanation
- Route = URL pattern + allowed methods (default: GET)
- View function = Python function that returns a response (string, template, JSON, tuple, or Response object)
2) URL parameters and converters — dynamic routes
URLs can carry variables. Want /hello/alice and /hello/bob to do different things? Use variable rules:
@app.route('/hello/<username>')
def hello(username):
return f'Hello, {username}!'
# with type converter
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post #{post_id}'
Converters: int, float, path (like string but allows slashes), uuid, and default string.
Why use them? Cleaner URLs, RESTful style, and easier server-side logic without query strings.
3) GET vs POST — forms and actions (tie to HTTP basics)
From HTTP basics you know GET is for retrieval and POST for creating/submitting. HTML forms default to GET unless you specify POST. Flask ties into this via the methods parameter and request object.
HTML form (client-side):
<form action="/submit" method="POST">
<input name="name" />
<button type="submit">Send</button>
</form>
Flask view (server-side):
from flask import request, redirect, url_for
@app.route('/submit', methods=['GET', 'POST'])
def submit():
if request.method == 'POST':
name = request.form.get('name')
return redirect(url_for('hello', username=name))
return 'Show the form (GET)'
Key points:
- Use
request.formfor form data (POST) andrequest.argsfor query strings (GET). - Use
redirect()andurl_for()to avoid hardcoding URLs and to follow the Post/Redirect/Get pattern (prevents form resubmission on refresh).
4) Templates and views — rendering HTML with Jinja2
Your previous lesson gave you HTML/CSS/JS. Now let Flask render that HTML and inject data. Flask uses Jinja2 templates — powerful, safe, and easy.
Folder structure (convention):
- templates/
- base.html
- index.html
- static/
- css/
- js/
Example: render a template from a view
from flask import render_template
@app.route('/')
def index():
users = ['alice', 'bob']
return render_template('index.html', users=users)
In templates/index.html (Jinja2):
{% extends 'base.html' %}
{% block content %}
<h1>Users</h1>
<ul>
{% for u in users %}
<li>{{ u }}</li>
{% endfor %}
</ul>
{% endblock %}
Security note: Jinja2 auto-escapes variables, preventing most XSS attacks — unless you intentionally mark safe.
5) Helpful utilities: url_for, abort, jsonify
url_for('func_name', arg=value)builds URLs dynamically; great for refactors and avoiding hardcoded strings.abort(404)raises an HTTP error (useful for missing resources).jsonify()returns JSON responses (useful when combining server APIs with client-side JS or building REST endpoints).
Example: API-like route
from flask import jsonify
@app.route('/api/user/<int:id>')
def api_user(id):
user = get_user_from_db(id)
if not user:
abort(404)
return jsonify(user)
Tie-in: This is how your client-side JavaScript (from the Web Foundations lesson) can fetch dynamic JSON and update the page.
6) Common confusions and best practices
- "Why is my form submitting a GET?" → Check your
methodattribute on the form. - "Why does my page keep reloading the form on refresh?" → Use Post/Redirect/Get: after POST, redirect to a GET route.
- Organize templates with
base.htmland blocks to avoid copy-paste. - For larger apps, use Blueprints to split routes logically (users, posts, api). That's the next step after mastering routes and views.
Quick workflow checklist
- Create venv and install Flask (you already did this in project setup).
- Define routes with
@app.route()— keep URLs semantic and RESTful when possible. - In POST handlers, read
request.formand thenredirect(url_for(...)). - Render templates with
render_template()and pass context variables. - Let client-side JS call
/api/...endpoints you make withjsonify().
Key takeaways
- Routes map URLs and HTTP methods to Python functions. Views (view functions) build responses.
- Use URL parameters to capture data from the path and templates to render HTML with dynamic content.
- Respect HTTP semantics: GET for retrieving, POST for submitting/creating. Use
request,redirect, andurl_forappropriately. - Keep your app organized: templates in
templates/, static files instatic/, and consider Blueprints when you grow.
"Routing + views = the choreography of web apps. Give them clear steps and your site won't trip on the dance floor."
If you want, I can generate a small starter Flask app that demonstrates all of the above (routes, templates, a form, and a JSON endpoint) ready to drop into your venv. Want that scaffold?
Comments (0)
Please sign in to leave a comment.
No comments yet. Be the first to comment!