Bootstrap

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),可能需要强制浏览器刷新缓存。可以通过以下方式解决:

  1. 在文件名中添加版本号
    例如,将 style.css 改为 style.v1.css,并在模板中更新引用:

    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.v1.css') }}">
    
  2. 使用查询参数
    在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应用实例。

好的!以下是关于 NginxDocker 部署 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 反向代理
  1. 创建 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 的负担。
  2. 启用配置文件
    将配置文件链接到 sites-enabled 目录:

    sudo ln -s /etc/nginx/sites-available/my_flask_app /etc/nginx/sites-enabled/
    
  3. 测试并重启 Nginx
    测试 Nginx 配置是否正确:

    sudo nginx -t
    

    如果没有错误,重启 Nginx:

    sudo systemctl restart nginx
    
  4. 运行 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。

  1. 创建 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
    
  2. 创建 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;
            }
        }
    }
    
  3. 启动服务

    docker-compose up -d
    

总结

Flask是一个灵活且易于上手的Web框架,适合快速开发小型应用和API。通过掌握路由、请求处理、模板渲染等基础知识,我们可以轻松构建功能丰富的Web应用。随着项目的复杂化,结合Flask扩展和部署工具,进一步提升应用的性能和可维护性。


参考文档

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;