Flask 新手教程:快速上手 Web 开发
Flask 是一个轻量级的 Python Web 框架,以其简洁、灵活和易于上手而闻名。它被称为“微框架”,因为它只提供了 Web 开发的核心组件,如路由、请求处理、模板引擎等,而将其他功能(如数据库集成、用户认证)交给扩展来实现。这种设计理念使得 Flask 非常适合小型项目、API 开发和原型设计,同时也能够通过扩展支持大型应用的开发。
本教程将带你从零开始,一步步学习 Flask 的基础知识,并通过一个简单的博客应用示例,让你了解如何使用 Flask 构建一个完整的 Web 应用。
1. 准备工作
在开始之前,确保你已经安装了 Python(建议使用 Python 3.6 或更高版本)和 pip
(Python 包管理器)。
1.1. 创建虚拟环境(推荐)
为了隔离项目依赖,建议创建一个虚拟环境:
“`bash
使用 Python 内置的 venv 模块
python3 -m venv venv
或者使用 virtualenv
virtualenv venv
“`
1.2. 激活虚拟环境
“`bash
macOS / Linux
source venv/bin/activate
Windows
venv\Scripts\activate
“`
1.3. 安装 Flask
在虚拟环境中安装 Flask:
bash
pip install Flask
2. 第一个 Flask 应用:Hello, World!
让我们从经典的 “Hello, World!” 程序开始。
2.1. 创建 app.py
创建一个名为 app.py
的文件,并输入以下代码:
“`python
from flask import Flask
app = Flask(name)
@app.route(‘/’)
def hello_world():
return ‘Hello, World!’
if name == ‘main‘:
app.run(debug=True)
“`
2.2. 代码解释
from flask import Flask
: 导入 Flask 类。app = Flask(__name__)
: 创建 Flask 应用实例。__name__
是一个特殊的 Python 变量,表示当前模块的名称。@app.route('/')
: 这是一个装饰器,用于将 URL 路径/
(根路径)映射到hello_world
函数。def hello_world():
: 定义一个视图函数,当用户访问根路径时,该函数会被调用。return 'Hello, World!'
: 视图函数返回一个字符串,作为 HTTP 响应的内容。if __name__ == '__main__':
: 确保只有当脚本直接运行时才启动 Flask 开发服务器。app.run(debug=True)
: 启动 Flask 开发服务器。debug=True
开启调试模式,当代码修改时,服务器会自动重新加载,并提供更详细的错误信息。
2.3. 运行应用
在终端中,进入 app.py
所在的目录,运行以下命令:
bash
python app.py
你将看到类似以下的输出:
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: xxx-xxx-xxx
在浏览器中访问 http://127.0.0.1:5000/
,你将看到 “Hello, World!”。
3. 路由和视图函数
Flask 的核心功能之一是路由。路由是将 URL 路径映射到视图函数的过程。
3.1. 多个路由
你可以在一个应用中定义多个路由:
“`python
from flask import Flask
app = Flask(name)
@app.route(‘/’)
def index():
return ‘
Index Page
‘
@app.route(‘/hello’)
def hello():
return ‘
Hello, World!
‘
@app.route(‘/user/
def show_user_profile(username):
# 显示用户的个人资料
return f’User {username}’
@app.route(‘/post/
def show_post(post_id):
# 显示给定 id 的文章,id 是一个整数
return f’Post {post_id}’
if name == ‘main‘:
app.run(debug=True)
“`
3.2. 动态路由
在上面的示例中,我们使用了两种动态路由:
<username>
: 匹配任何字符串,并将其作为username
参数传递给视图函数。<int:post_id>
: 匹配一个整数,并将其作为post_id
参数传递给视图函数。
Flask 还支持其他类型的变量规则,如:
<float:variable_name>
<path:variable_name>
<uuid:variable_name>
3.3. HTTP 方法
默认情况下,路由只响应 GET 请求。你可以使用 methods
参数指定允许的 HTTP 方法:
“`python
from flask import Flask, request
app = Flask(name)
@app.route(‘/login’, methods=[‘GET’, ‘POST’])
def login():
if request.method == ‘POST’:
# 处理 POST 请求(例如,验证用户名和密码)
return ‘Login successful!’
else:
# 处理 GET 请求(例如,显示登录表单)
return ‘Please login:’
if name == ‘main‘:
app.run(debug=True)
“`
4. 模板渲染
直接在 Python 代码中编写 HTML 既不方便也不利于维护。Flask 使用 Jinja2 模板引擎来渲染 HTML 模板。
4.1. 创建模板目录
在你的项目目录下创建一个名为 templates
的文件夹。Flask 会自动在这个文件夹中查找模板文件。
4.2. 创建模板文件
在 templates
目录下创建两个 HTML 文件:
index.html
:
“`html
Index Page
Welcome, {{ name }}!
“`
hello.html
:
“`html
Hello, {{ name }}!
“`
4.3. 修改 app.py
“`python
from flask import Flask, render_template, request
app = Flask(name)
@app.route(‘/’)
def index():
return render_template(‘index.html’, name=’User’)
@app.route(‘/hello/
def hello(name):
return render_template(‘hello.html’, name=name)
if name == ‘main‘:
app.run(debug=True)
“`
4.4. 代码解释
from flask import render_template
: 导入render_template
函数。render_template('index.html', name='User')
:render_template
函数渲染index.html
模板,并将name
变量传递给模板。{{ name }}
: 在模板中,{{ name }}
会被替换为name
变量的值。
现在,访问 http://127.0.0.1:5000/
和 http://127.0.0.1:5000/hello/yourname
,你将看到渲染后的 HTML 页面。
5. 静态文件
Web 应用通常需要提供静态文件,如 CSS、JavaScript 和图片。
5.1. 创建静态目录
在你的项目目录下创建一个名为 static
的文件夹。Flask 会自动在这个文件夹中查找静态文件。
5.2. 创建静态文件
在 static
目录下创建一个 CSS 文件:
style.css
:
css
body {
background-color: #f0f0f0;
font-family: sans-serif;
}
5.3. 在模板中引用静态文件
在 index.html
和 hello.html
的 <head>
部分添加以下代码:
html
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
5.4. 代码解释
url_for('static', filename='style.css')
:url_for
函数生成静态文件的 URL。第一个参数是端点名称(对于静态文件,通常是'static'
),filename
参数是静态文件的相对路径。
现在,重新加载页面,你将看到 CSS 样式生效。
6. 构建一个简单的博客应用
现在,我们将结合前面学到的知识,构建一个简单的博客应用。
6.1. 项目结构
my_blog/
├── app.py
├── templates/
│ ├── layout.html
│ ├── index.html
│ └── post.html
└── static/
└── style.css
6.2. app.py
“`python
from flask import Flask, render_template, request, redirect, url_for
app = Flask(name)
模拟数据库
posts = [
{‘id’: 1, ‘title’: ‘First Post’, ‘content’: ‘This is the first post.’},
{‘id’: 2, ‘title’: ‘Second Post’, ‘content’: ‘This is the second post.’},
]
@app.route(‘/’)
def index():
return render_template(‘index.html’, posts=posts)
@app.route(‘/post/
def post(post_id):
post = next((p for p in posts if p[‘id’] == post_id), None)
if post:
return render_template(‘post.html’, post=post)
else:
return ‘Post not found’, 404
@app.route(‘/add’, methods=[‘GET’, ‘POST’])
def add_post():
if request.method == ‘POST’:
title = request.form[‘title’]
content = request.form[‘content’]
new_post = {‘id’: len(posts) + 1, ‘title’: title, ‘content’: content}
posts.append(new_post)
return redirect(url_for(‘index’))
return render_template(‘add_post.html’) #假设有add_post.html
@app.route(‘/delete/
def delete_post(post_id):
global posts
posts = [p for p in posts if p[‘id’] != post_id]
return redirect(url_for(‘index’))
if name == ‘main‘:
app.run(debug=True)
“`
6.3. templates/layout.html
“`html
“`
6.4. templates/index.html
“`html
{% extends “layout.html” %}
{% block title %}Home{% endblock %}
{% block content %}
My Blog
-
{% for post in posts %}
-
{{ post.title }}
{% endfor %}
</ul>
{% endblock %}
“`
6.5. templates/post.html
html
{% extends "layout.html" %}
{% block title %}{{ post.title }}{% endblock %}
{% block content %}
<h1>{{ post.title }}</h1>
<p>{{ post.content }}</p>
{% endblock %}
6.6 templates/add_post.html
html
{% extends "layout.html" %}
{% block title %}Add Post{% endblock %}
{% block content %}
<h1>Add New Post</h1>
<form method="post">
<label for="title">Title:</label><br>
<input type="text" id="title" name="title"><br>
<label for="content">Content:</label><br>
<textarea id="content" name="content"></textarea><br>
<input type="submit" value="Submit">
</form>
{% endblock %}
6.7. static/style.css
“`css
body {
background-color: #f0f0f0;
font-family: sans-serif;
}
h1, h2 {
color: #333;
}
ul {
list-style: none;
padding: 0;
}
li {
margin-bottom: 1em;
border: 1px solid #ccc;
padding: 1em;
}
“`
6.8. 代码解释
layout.html
: 定义了博客应用的整体布局,包含标题、CSS 链接和一个内容块。index.html
: 显示博客文章列表,并使用{% extends "layout.html" %}
继承layout.html
的布局。post.html
: 显示单篇博客文章的内容。- Jinja2 模板语法:
{% extends "layout.html" %}
: 继承模板。{% block title %}{% endblock %}
: 定义一个名为title
的块,子模板可以覆盖这个块的内容。{% for post in posts %}
: 循环遍历posts
列表。{{ post.title }}
: 显示post
对象的title
属性。
- 表单: 在
add_post.html
创建了一个简单的表单来增加新文章。 - 删除文章:在
index.html
创建了一个删除按钮来删除文章,使用delete_post
路由来处理删除逻辑
6.9 运行应用
运行 python app.py
,在浏览器中访问 http://127.0.0.1:5000/
,你将看到一个简单的博客应用,可以浏览文章、添加新文章。
7. 总结
本教程介绍了 Flask 的基础知识,包括路由、视图函数、模板渲染、静态文件处理,以及如何构建一个简单的博客应用。Flask 的简洁性和灵活性使得它成为 Python Web 开发的理想选择。
要深入学习 Flask,建议阅读官方文档:https://flask.palletsprojects.com/
此外,你还可以学习以下 Flask 扩展,以增强你的应用功能:
- Flask-SQLAlchemy: 提供对 SQLAlchemy(一个强大的 Python SQL 工具包和对象关系映射器)的支持。
- Flask-WTF: 与 WTForms(一个灵活的表单渲染和验证库)集成。
- Flask-Login: 提供用户会话管理功能。
- Flask-RESTful: 帮助你快速构建 RESTful API。
- Flask-Mail: 简化邮件发送功能。
希望本教程能帮助你快速入门 Flask Web 开发! 通过不断的实践和学习,你将能够使用 Flask 构建出功能强大且易于维护的 Web 应用。