First introduction to Flask - A guide to getting started with Python lightweight web framework
Have you ever had this thought?
- Use Python to build a minimalist message board and let your friends leave after just two sentences;
- Write an API to expose the data you crawled to mini programs or front-end pages;
- Or simply create a Personal Station, where you can post your practice projects and show them to your future self.
If so, then Flask this "Python micro-frame ceiling entry model" is definitely your weapon!
1. Introduction to Flask
1.1 What is Flask?
Flask is a Python microframework created by Armin Ronacher in 2010. It is built on two very reliable shoulders: Werkzeug WSGI toolbox and Jinja2 template engine. Today, it has long become one of the top Python web frameworks.
The "micro" here does not mean that it has few functions, but that its core is extremely simple - only the most basic parts of web development are retained: routing, templates, and responses. Other functions such as database, form validation, user authentication, etc. are all installed on demand through extensions, without forcing you to use any specific tools or libraries.
1.2 Core features of Flask
- Lightweight and easy to use: The core code only has a few thousand lines, and you can run the first complete application in half a day.
- Extremely high flexibility: The project structure and database selection are all up to you.
- Rich extension ecosystem: Official and third-party extensions cover almost all web development scenarios.
- Full community active documents: If you encounter a problem, you can find the answer by searching for it. It is extremely friendly to novices.
1.3 Comparison with Python frameworks of the same level
2. Flask installation and environment preparation
2.1 Environmental requirements
- Python 3.7 or higher
- pip package manager
- Virtual environment (strongly recommended to avoid contaminating the system Python environment)
2.2 Create a virtual environment
First create a new project folder, for example calledflask-demo, then open a terminal and execute:
# 1. 创建虚拟环境(flask_env 是环境名,可自定义)
python -m venv flask_env
# 2. 激活虚拟环境
# macOS / Linux
source flask_env/bin/activate
# Windows (CMD / 旧版 PowerShell)
flask_env\Scripts\activate
If it is the **new version of PowerShell (Win11/Win10 20H2+)**, you need to allow local script execution first:
```powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
```
Then use:
```powershell
.\flask_env\Scripts\Activate.ps1
```
Activate the environment.
After activation is successful, a message will appear in front of the terminal.(flask_env)logo, all subsequent operations will be performed in this isolated small world.
# 3. 升级 pip(可选但推荐)
pip install --upgrade pip
2.3 Install Flask
# 安装最新稳定版 Flask
pip install Flask
# 验证安装(看到版本号就说明成功)
python -c "import flask; print(flask.__version__)"
3. The first Flask application: Hello World!
Knock on the blackboard! Although the following code is short, it contains all core elements of the Flask application.
3.1 Create application files
existflask-demoCreate a new directoryapp.py:
# app.py
from flask import Flask
# 1. 创建 Flask 应用实例
# __name__ 是 Flask 的「导航员」,告诉它从当前文件所在目录找 templates / static 等资源
app = Flask(__name__)
# 2. 定义路由装饰器 + 处理函数
# @app.route('/') 把「根路径 http://127.0.0.1:5000/」映射到下面的 hello_world 函数
@app.route('/')
def hello_world():
# 处理函数的返回值,就是给浏览器的响应内容
return '<h1>🎉 恭喜你,第一个 Flask 应用跑通了!</h1>'
# 3. 启动应用(仅在直接运行 app.py 时生效)
if __name__ == '__main__':
# debug=True 开启调试模式:代码修改后自动重启、显示详细错误信息
app.run(debug=True)
3.2 Run and access the application
Execute in the terminal that activates the virtual environment:
The terminal will print information similar to the following:
* Running on http://127.0.0.1:5000/
* Restarting with stat
* Debugger is active!
* Debugger PIN: xxx-xxx-xxx
Open browser to visithttp://127.0.0.1:5000/, you can see your Hello World page!
`app.run(debug=True)`Debug mode turned on is **very dangerous** - it exposes code, configuration, and even allows users to execute Python code on the server!
It’s okay to use it for beginners, but when you actually go online, you must turn it off and replace it with a professional WSGI server (such as Gunicorn).
4. Flask core concept 1: routing system
Routing is the rule that binds URL paths and processing functions. It is the "entry manager" of the entire Flask application.
4.1 Basic routing
# 根路径
@app.route('/')
def index():
return '首页'
# 带固定字符串的路径
@app.route('/about')
def about():
return '关于我们'
4.2 Routing with variables (URL converter)
you can use<变量名>Add dynamic content to the URL, and also cooperate with<转换器:变量名>Limit variable types:
# 字符串变量(默认)
@app.route('/user/<username>')
def user_profile(username):
return f'你好,{username}!'
# 整数变量
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'这是第 {post_id} 篇文章'
# 路径变量(含斜杠)
@app.route('/files/<path:file_path>')
def show_file(file_path):
# 模拟显示文件路径,实际应用一定要注意安全!
return f'你请求的文件路径是:{file_path}'
4.3 Restrict HTTP methods
By default, Flask routing only acceptsGETask. If you need to acceptPOST、PUTWaiting method, in@app.routerigamethodsThe parameters are:
from flask import request # 别忘了导入 request 对象!
# 同时接受 GET 和 POST 请求
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
# 处理 POST 请求:比如获取表单数据
return '正在处理登录请求...'
else:
# 处理 GET 请求:比如显示登录表单
return '<form method="post"><input type="text" name="username"><button type="submit">登录</button></form>'
# 处理 GET 查询参数(例如 /search?q=Flask)
@app.route('/search')
def search():
# request.args.get('参数名', '默认值') 获取 URL 中的查询参数
keyword = request.args.get('q', '暂无关键词')
return f'搜索关键词:{keyword}'
5. Flask core concept 2: Jinja2 template engine
Spelling HTML directly in Python code is ugly and difficult to maintain! Flask has a built-in Jinja2 template engine, allowing you to write HTML (view) and Python (logic) separately.
5.1 Basic template usage
- First of all
flask-demoCreate a new directorytemplatesFolder (The name must be templates and cannot be changed!)
- in
templatesnew inhello.html:
<!-- templates/hello.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Jinja2 变量:用 {{ 变量名 }} 包裹 -->
<title>{{ page_title }}</title>
</head>
<body>
<h1>你好,{{ user_name }}!👋</h1>
<!-- Jinja2 条件判断:用 {% if ... %} {% elif ... %} {% else %} {% endif %} 包裹 -->
{% if user_age >= 18 %}
<p>你已经成年啦!</p>
{% else %}
<p>你还未成年哦~</p>
{% endif %}
<!-- Jinja2 循环:用 {% for ... in ... %} {% endfor %} 包裹 -->
<h3>最近读过的书:</h3>
<ul>
{% for book in books %}
<li>{{ book.title }} - {{ book.author }}</li>
{% endfor %}
</ul>
</body>
</html>
- in
app.pyused inrender_templateRender template:
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/hello/<name>/<int:age>')
def hello_template(name, age):
# 准备要传给模板的数据
books = [
{'title': 'Flask Web开发实战', 'author': '李辉'},
{'title': 'Python编程从入门到实践', 'author': '埃里克·马瑟斯'}
]
# 第一个参数是模板文件名,后面的参数是传给模板的键值对
return render_template(
'hello.html',
page_title=f'{name}的主页',
user_name=name,
user_age=age,
books=books
)
5.2 Template inheritance (avoid duplicating code)
If your website has multiple pages with the same header, tail, and navigation, then using template inheritance can significantly reduce duplicate code.
- First create a Basic Template
base.html, put content common to all pages, and use{% block 块名 %}{% endblock %}Reserve the location where subpages can be modified:
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}小站首页{% endblock %} | Flask入门练手</title>
<!-- 后续加静态文件 CSS/JS 用 -->
</head>
<body>
<header>
<h1>我的 Flask 小站</h1>
<nav>
<a href="/">首页</a> |
<a href="/about">关于</a>
</nav>
</header>
<!-- 主要内容块,子页面必须覆盖 -->
<main>
{% block content %}{% endblock %}
</main>
<footer>
<p>© 2024 道满PythonAI</p>
</footer>
</body>
</html>
- Create another subtemplate
child_about.html, inherit the base template and overwrite the blocks that need to be modified:
<!-- templates/child_about.html -->
<!-- 第一行必须写继承语句 -->
{% extends "base.html" %}
<!-- 覆盖 title 块 -->
{% block title %}关于我们{% endblock %}
<!-- 覆盖 content 块 -->
{% block content %}
<h2>关于我们</h2>
<p>这是一个用 Flask 搭建的入门练手小站~</p>
{% endblock %}
- in
app.pyAdd route here:
@app.route('/about')
def about():
return render_template('child_about.html')
6. Static file management (CSS/JS/images)
CSS, JavaScript, and images do not require dynamically generated files, Flask will automaticallystaticProvided in the folder (name must be static and cannot be changed!).
6.1 Basic usage
- in
flask-demoCreate a new directorystaticfolder and create it in itcss、js、imagessubfolder
- For example, in
static/cssnew instyle.css:
/* static/css/style.css */
body {
background-color: #f0f2f5;
font-family: 'Microsoft YaHei', sans-serif;
}
h1 {
color: #1890ff;
}
- Use in templates
url_for('static', filename='子路径/文件名')Generate the URL of the static file:
<!-- 修改 templates/base.html 的 head 部分 -->
<head>
...
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
7. Complete practice project: simple message board
Now let's combine what we learned earlier and make a small application that can leave messages and delete them!
7.1 Project structure
flask-demo/
├── app.py # 应用主文件
├── flask_env/ # 虚拟环境(不用管)
├── static/ # 静态文件
│ └── css/
│ └── style.css
└── templates/ # 模板文件
├── base.html
└── index.html
7.2 Code implementation
1. Modify firstbase.htmlandstyle.css(You can refer to Sections 5 and 6 to slightly optimize the visual effects to make it more like a message board)
2. Then modifyapp.py:
from flask import Flask, render_template, request, redirect, url_for, flash
from datetime import datetime
app = Flask(__name__)
# 必须设置 SECRET_KEY 才能使用 flash 消息!
# 实际应用中要用随机生成的密钥,不要用硬编码的
app.secret_key = 'your-random-secret-key-here'
# 模拟数据存储(内存里的列表,重启应用数据会清空,学了数据库后可以换成 MySQL / SQLite)
messages = []
# 首页:显示留言列表和留言表单
@app.route('/')
def index():
return render_template('index.html', messages=messages)
# 处理新增留言的 POST 请求
@app.route('/add_message', methods=['POST'])
def add_message():
# 获取表单数据
name = request.form.get('name', '').strip()
content = request.form.get('content', '').strip()
if name and content:
# 添加留言到列表
messages.append({
'id': len(messages) + 1, # 模拟 ID
'name': name,
'content': content,
'time': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
})
# flash 消息:显示一次就消失的提示
flash('🎉 留言添加成功!', 'success')
else:
flash('⚠️ 昵称和留言内容不能为空!', 'error')
# redirect(url_for('函数名')) 跳转到指定路由,避免重复提交表单
return redirect(url_for('index'))
# 处理删除留言的请求
@app.route('/delete/<int:msg_id>')
def delete_message(msg_id):
global messages
# 过滤掉要删除的留言
messages = [msg for msg in messages if msg['id'] != msg_id]
flash('🗑️ 留言删除成功!', 'info')
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
3. Finally createtemplates/index.html:
<!-- templates/index.html -->
{% extends "base.html" %}
{% block title %}简易留言板{% endblock %}
{% block content %}
<!-- 显示 flash 消息 -->
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-messages">
{% for category, msg in messages %}
<div class="flash {{ category }}">{{ msg }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
<!-- 留言表单 -->
<div class="form-box">
<h3>留下你的足迹 ✍️</h3>
<form action="{{ url_for('add_message') }}" method="post">
<label for="name">昵称:</label>
<input type="text" id="name" name="name" placeholder="请输入昵称" required>
<br><br>
<label for="content">留言:</label>
<textarea id="content" name="content" rows="4" placeholder="请输入留言内容" required></textarea>
<br><br>
<button type="submit">发送</button>
</form>
</div>
<!-- 留言列表 -->
<div class="message-box">
<h3>留言墙 📋</h3>
{% if messages %}
<ul class="message-list">
{% for msg in messages %}
<li class="message-item">
<div class="msg-header">
<span class="msg-name">{{ msg.name }}</span>
<span class="msg-time">{{ msg.time }}</span>
<a href="{{ url_for('delete_message', msg_id=msg.id) }}" class="delete-btn">删除</a>
</div>
<div class="msg-content">{{ msg.content }}</div>
</li>
{% endfor %}
</ul>
{% else %}
<p class="no-msg">暂无留言,快来抢沙发吧!🛋️</p>
{% endif %}
</div>
{% endblock %}
Execute the following command in the Python terminal to generate a random, secure 32-bit key:
```python
import secrets
print(secrets.token_hex(16))
```
Replace the output result with`app.py`inside`app.secret_key`That’s it.
Flask's simplicity makes it a great starting choice for learning web development! It is recommended that you:
1. First open the message board for this article and try changing the style and functions;
2. Learn Flask extensions (such as Flask-SQLAlchemy to operate the database);
3. Finally try to make a more complete project (such as personal blog, Todo List).
Summarize
By studying this article, you have mastered all the core foundation of Flask:
- How to set up a Flask development environment (virtual environment + install Flask)
- How to create and run your first Flask application
- How to use the routing system (basic routing, routing with variables, HTTP methods)
- How to use Jinja2 template engine (variables, conditions, loops, inheritance)
- How to manage static files
- How to make a complete introductory training program
Flask's flexibility and scalability make it ideal for web applications of all sizes, from simple APIs to complex enterprise-level projects! Next, continue to learn Flask extensions to make your application more and more powerful~