Flask 实战指南

FreeGuideOnline 最新 2026-07-15
导航栏
{% block content %}{% endblock %}
```

子模板继承:

<!-- templates/index.html -->
{% extends 'base.html' %}
{% block title %}首页{% endblock %}
{% block content %}
    <h1>欢迎来到 Flask 博客</h1>
{% endblock %}

视图函数渲染模板:

from flask import render_template

@app.route('/')
def index():
    return render_template('index.html')

传递数据到模板

@app.route('/post/<int:post_id>')
def show_post(post_id):
    post = get_post(post_id)  # 从数据库获取文章
    return render_template('post.html', post=post)

模板中访问:

<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>

静态文件管理

静态文件(CSS、JS、图片)放置在 static 文件夹,通过 url_for('static', filename='style.css') 生成路径。

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/app.js') }}"></script>

表单处理与请求数据

接收 GET/POST 参数

from flask import request

@app.route('/search')
def search():
    query = request.args.get('q', '')
    return f'搜索内容: {query}'

@app.route('/login', methods=['POST'])
def login_post():
    username = request.form['username']
    password = request.form['password']
    # 验证用户...

文件上传

from werkzeug.utils import secure_filename

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == 'POST':
        f = request.files['file']
        filename = secure_filename(f.filename)
        f.save(os.path.join('uploads', filename))
        return '上传成功'
    return render_template('upload.html')

数据库集成:使用 Flask-SQLAlchemy

安装与配置

pip install flask-sqlalchemy

配置 app.py

from flask_sqlalchemy import SQLAlchemy

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
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)
    email = db.Column(db.String(120), unique=True, nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

创建数据库表:

flask shell
>>> from app import db
>>> db.create_all()

增删改查示例

# 创建
user = User(username='admin', email='admin@example.com')
db.session.add(user)
db.session.commit()

# 查询
posts = Post.query.filter_by(user_id=1).all()
post = Post.query.get(1)

# 更新
post.title = '新标题'
db.session.commit()

# 删除
db.session.delete(post)
db.session.commit()

用户认证与会话管理

实现注册与登录

使用 Flask-Login 简化用户会话管理。

pip install flask-login

初始化:

from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user

login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.init_app(app)

class User(UserMixin, db.Model):
    # 之前的字段...
    password_hash = db.Column(db.String(128))

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

密码哈希与验证(使用 Werkzeug)

from werkzeug.security import generate_password_hash, check_password_hash

# 注册时
hashed = generate_password_hash('your_password')
user = User(username='test', password_hash=hashed)
db.session.add(user)

# 登录验证
if check_password_hash(user.password_hash, 'input_password'):
    login_user(user)

保护路由

@app.route('/dashboard')
@login_required
def dashboard():
    return f'欢迎 {current_user.username}'

项目结构优化:蓝图(Blueprint)

当应用变大时,使用蓝图组织代码。例如创建 auth 蓝图。

auth/__init__.py

from flask import Blueprint

auth_bp = Blueprint('auth', __name__, url_prefix='/auth')

from . import views

auth/views.py

from . import auth_bp
from flask import render_template, redirect, url_for, request, flash
from flask_login import login_user, logout_user, login_required

@auth_bp.route('/login', methods=['GET', 'POST'])
def login():
    # 登录逻辑
    ...

主应用注册蓝图:

from auth import auth_bp

app.register_blueprint(auth_bp)

推荐目录结构:

flask-blog/
├── app/
│   ├── auth/
│   ├── blog/
│   ├── templates/
│   └── static/
├── app.py
└── config.py

RESTful API 开发与 JSON 响应

返回 JSON

from flask import jsonify

@app.route('/api/posts', methods=['GET'])
def get_posts_api():
    posts = Post.query.all()
    return jsonify([{'id': p.id, 'title': p.title} for p in posts])

使用 Flask-RESTful 扩展

pip install flask-restful

简便方式构建接口:

from flask_restful import Api, Resource

api = Api(app)

class PostResource(Resource):
    def get(self, post_id):
        post = Post.query.get_or_404(post_id)
        return {'id': post.id, 'title': post.title}

api.add_resource(PostResource, '/api/post/<int:post_id>')

错误处理与自定义错误页面

@app.errorhandler(404)
def not_found_error(error):
    return render_template('404.html'), 404

@app.errorhandler(500)
def internal_error(error):
    db.session.rollback()
    return render_template('500.html'), 500

部署上线建议

使用 Gunicorn + Nginx

生产环境不要用 Flask 自带服务器。安装 Gunicorn:

pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:8000 app:app

通过 Nginx 反向代理:

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

环境变量与配置管理

使用 .envpython-dotenv 管理敏感信息:

# .env
FLASK_SECRET_KEY=your-secret-key
DATABASE_URL=postgresql://...

app.py 中加载:

from dotenv import load_dotenv
load_dotenv()
app.config['SECRET_KEY'] = os.getenv('FLASK_SECRET_KEY')