Flask学习入门笔记
前言
Flask是一个轻量级的Python Web框架,适合快速开发小型Web应用和API。它灵活、易扩展,并且拥有丰富的插件生态系统。
1. 安装Flask
首先,我们需要安装Flask。可以通过pip
来安装:
pip install Flask
2. 创建一个简单的Flask应用
创建一个最简单的Flask应用只需要几行代码:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
代码解析:
Flask(__name__)
:创建一个Flask应用实例。__name__
参数用于确定应用的根目录。@app.route('/')
:定义路由。当用户访问根路径/
时,会调用hello_world
函数。app.run(debug=True)
:启动Flask开发服务器。debug=True
表示开启调试模式,代码修改后会自动重启服务器。
运行应用:
将上述代码保存为app.py
,然后在终端运行:
python app.py
打开浏览器,访问http://127.0.0.1:5000/
,页面显示如下:
3. 路由与视图函数
Flask通过路由将URL与视图函数绑定。视图函数负责处理请求并返回响应。
3.1 基本路由
@app.route('/about')
def about():
return 'This is the about page.'
访问http://127.0.0.1:5000/about
,页面显示如下:
3.2 动态路由
我们可以通过<variable>
来定义动态路由。
@app.route('/user/<username>')
def show_user_profile(username):
return f'User {username}'
访问http://127.0.0.1:5000/user/john
,页面显示如下:
3.3 HTTP方法
默认情况下,路由只响应GET
请求。我们可以通过methods
参数指定其他HTTP方法:
from flask import request
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return 'Login POST request'
else:
return 'Login GET request'
4. 请求与响应
4.1 获取请求数据
Flask通过request
对象来处理请求数据。我们可以获取URL参数、表单数据、JSON数据等。
from flask import request
@app.route('/search')
def search():
query = request.args.get('q') # 获取URL参数
return f'Search query: {query}'
访问http://127.0.0.1:5000/search?q=flask
,页面显示如下:
4.2 返回响应
视图函数可以返回字符串、HTML、JSON等。Flask会自动将其转换为HTTP响应。
from flask import jsonify
@app.route('/api/data')
def get_data():
data = {'name': 'John', 'age': 30}
return jsonify(data) # 返回JSON响应
访问http://127.0.0.1:5000/api/data
,页面显示如下:
5. 模板渲染
Flask使用Jinja2模板引擎来渲染HTML页面。模板文件通常放在templates
目录下。
5.1 基本模板渲染
创建一个templates/index.html
文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Home</title>
</head>
<body>
<h1>Hello, {{ name }}!</h1>
</body>
</html>
在视图函数中渲染模板:
from flask import render_template
@app.route('/hello/<name>')
def hello(name):
return render_template('index.html', name=name)
访问http://127.0.0.1:5000/hello/john
,页面显示如下:
5.2 模板继承
Jinja2支持模板继承,可以减少重复代码。创建一个基础模板templates/base.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}My Site{% endblock %}</title>
</head>
<body>
<header>
<h1>My Site</h1>
</header>
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
然后在子模板中继承基础模板,创建一个 about.html
:
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
<h2>Welcome to the home page!</h2>
{% endblock %}
然后在app.py
文件中添加一个新的路由:
@app.route('/about')
def about():
return render_template('about.html')
访问 http://127.0.0.1:5000/about
,页面显示如下:
6. 静态文件
在Web开发中,静态文件(如CSS、JavaScript、图片等)是网站的重要组成部分。Flask默认会将 static
目录作为静态文件的根目录,我们可以通过 url_for
函数在模板中引用这些文件。
6.1 静态文件的目录结构
Flask项目的典型目录结构如下:
my_flask_app/
│
├── app.py
├── templates/
│ ├── index.html
│ └── base.html
└── static/
├── css/
│ └── style.css
├── js/
│ └── script.js
└── images/
└── logo.png
static/
目录是Flask默认的静态文件存放位置。- 可以在
static/
目录下创建子目录(如css/
、js/
、images/
)来更好地组织文件。
6.2 在模板中引用静态文件
Flask提供了 url_for
函数来生成静态文件的URL。url_for
的第一个参数是 'static'
,表示引用静态文件;第二个参数 filename
是文件的路径(相对于 static/
目录)。
6.2.1 引用CSS文件
在模板中引用CSS文件:
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Flask App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h1>Welcome to My Flask App!</h1>
</body>
</html>
6.2.2 引用JavaScript文件
在模板中引用JavaScript文件:
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Flask App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h1>Welcome to My Flask App!</h1>
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>
6.2.3 引用图片文件
在模板中引用图片文件:
<!-- templates/index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>My Flask App</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
<h1>Welcome to My Flask App!</h1>
<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">
<script src="{{ url_for('static', filename='js/script.js') }}"></script>
</body>
</html>
6.3 修改静态文件的URL前缀
默认情况下,Flask会将静态文件的URL前缀设置为 /static/
。如果你需要修改这个前缀,可以在创建Flask应用时通过 static_url_path
参数进行配置:
from flask import Flask
app = Flask(__name__, static_url_path='/assets')
@app.route('/')
def home():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
此时,静态文件的URL前缀会变为 /assets/
。例如,style.css
的URL会变成 /assets/css/style.css
。
6.4 静态文件的缓存问题
在生产环境中,浏览器会缓存静态文件以提高性能。如果你更新了静态文件(如CSS或JavaScript),可能需要强制浏览器刷新缓存。可以通过以下方式解决:
-
在文件名中添加版本号
例如,将style.css
改为style.v1.css
,并在模板中更新引用:<link rel="stylesheet" href="{{ url_for('static', filename='css/style.v1.css') }}">
-
使用查询参数
在URL中添加一个查询参数(如时间戳或版本号):<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}?v=1.0">
6.5 静态文件的CDN加速
在生产环境中,可以将静态文件托管到CDN(内容分发网络)以提高加载速度。只需将 url_for
生成的URL替换为CDN的URL即可:
<link rel="stylesheet" href="https://cdn.example.com/css/style.css">
6.6 静态文件的调试模式
在开发环境中,Flask会自动处理静态文件。但在生产环境中,建议使用Web服务器(如Nginx或Apache)来直接提供静态文件,以提高性能。
7. Flask扩展
Flask拥有丰富的扩展生态系统,可以帮助你快速实现各种功能。以下是一些常用的扩展:
- Flask-SQLAlchemy:数据库ORM
- Flask-WTF:表单处理
- Flask-Login:用户认证
- Flask-RESTful:构建RESTful API
7.1 安装扩展
可以通过pip
安装扩展:
pip install Flask-SQLAlchemy
7.2 使用扩展
以Flask-SQLAlchemy为例:
from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
@app.route('/users')
def list_users():
users = User.query.all()
return render_template('users.html', users=users)
8. 部署Flask应用
Flask自带的开发服务器不适合生产环境。我们可以使用以下工具来部署Flask应用:
- Gunicorn:一个Python WSGI HTTP服务器
- Nginx:反向代理服务器
- Docker:容器化部署
8.1 使用Gunicorn部署
安装Gunicorn:
pip install gunicorn
然后使用Gunicorn运行Flask应用:
gunicorn -w 4 app:app
-w 4
表示启动4个工作进程,app:app
表示Flask应用实例。
好的!以下是关于 Nginx 和 Docker 部署 Flask 应用的补充说明,帮助你更全面地了解如何将 Flask 应用部署到生产环境。
8.2 使用 Nginx 作为反向代理服务器
Nginx 是一个高性能的 HTTP 服务器和反向代理服务器。在生产环境中,通常会将 Nginx 放在 Gunicorn 前面,用于处理静态文件、负载均衡、SSL 终止等任务。
8.2.1 安装 Nginx
在 Linux 系统上,可以使用包管理器安装 Nginx:
# Ubuntu/Debian
sudo apt update
sudo apt install nginx
# CentOS/RHEL
sudo yum install nginx
安装完成后,启动 Nginx 服务:
sudo systemctl start nginx
8.2.2 配置 Nginx 反向代理
-
创建 Nginx 配置文件
在/etc/nginx/sites-available/
目录下创建一个新的配置文件(如my_flask_app
):sudo nano /etc/nginx/sites-available/my_flask_app
添加以下内容:
server { listen 80; server_name your_domain_or_ip; location / { proxy_pass http://127.0.0.1:8000; # 将请求转发给 Gunicorn proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static { alias /path/to/your/flask/app/static; # 直接提供静态文件 } }
server_name
:填写你的域名或 IP 地址。proxy_pass
:将请求转发给 Gunicorn(假设 Gunicorn 运行在127.0.0.1:8000
)。location /static
:Nginx 直接提供静态文件,减轻 Gunicorn 的负担。
-
启用配置文件
将配置文件链接到sites-enabled
目录:sudo ln -s /etc/nginx/sites-available/my_flask_app /etc/nginx/sites-enabled/
-
测试并重启 Nginx
测试 Nginx 配置是否正确:sudo nginx -t
如果没有错误,重启 Nginx:
sudo systemctl restart nginx
-
运行 Gunicorn
使用 Gunicorn 启动 Flask 应用:gunicorn -w 4 app:app
现在,访问
http://your_domain_or_ip
,Nginx 会将请求转发给 Gunicorn。
8.3 使用 Docker 容器化部署
Docker 是一种容器化技术,可以将应用及其依赖打包到一个容器中,方便部署和扩展。
8.3.1 创建 Dockerfile
在 Flask 项目的根目录下创建一个 Dockerfile
:
# 使用官方 Python 镜像作为基础镜像
FROM python:3.9-slim
# 设置工作目录
WORKDIR /app
# 复制项目文件到容器中
COPY . .
# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt
# 暴露端口
EXPOSE 5000
# 设置环境变量
ENV FLASK_APP=app.py
ENV FLASK_ENV=production
# 启动应用
CMD ["gunicorn", "-w", "4", "app:app"]
8.3.2 构建 Docker 镜像
在项目根目录下运行以下命令,构建 Docker 镜像:
docker build -t my_flask_app .
8.3.3 运行 Docker 容器
使用以下命令运行容器:
docker run -d -p 5000:5000 --name my_flask_app my_flask_app
-d
:以守护进程模式运行容器。-p 5000:5000
:将容器的 5000 端口映射到主机的 5000 端口。--name my_flask_app
:为容器指定名称。
8.3.4 使用 Docker Compose
如果需要同时运行多个服务(如 Flask 应用和 Nginx),可以使用 Docker Compose。
-
创建
docker-compose.yml
文件:version: '3' services: web: build: . ports: - "5000:5000" volumes: - .:/app command: gunicorn -w 4 app:app nginx: image: nginx:latest ports: - "80:80" volumes: - ./nginx.conf:/etc/nginx/nginx.conf depends_on: - web
-
创建 Nginx 配置文件(
nginx.conf
):events {} http { server { listen 80; server_name your_domain_or_ip; location / { proxy_pass http://web:5000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /static { alias /app/static; } } }
-
启动服务:
docker-compose up -d
总结
Flask是一个灵活且易于上手的Web框架,适合快速开发小型应用和API。通过掌握路由、请求处理、模板渲染等基础知识,我们可以轻松构建功能丰富的Web应用。随着项目的复杂化,结合Flask扩展和部署工具,进一步提升应用的性能和可维护性。