Python Flask 快速入门:路由、模板、Jinja2、WTForms、SQLAlchemy
Introduction
Flask 是 Python 最流行的轻量级 Web 框架。本文从最小的 Hello World 开始,详解 Flask 的路由、模板渲染、Jinja2 语法、WTForms 表单验证、SQLAlchemy ORM、以及 Flask 蓝图模块化开发。
---
最小 Flask 应用
pip install flask
# app.py
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
@app.route('/user/<name>')
def greet(name):
return f'Hello, {name}!'
if __name__ == '__main__':
app.run(debug=True, port=5000)
路由与变量规则
@app.route('/post/<int:post_id>')
def get_post(post_id):
return f'Post ID: {post_id}'
@app.route('/user/<username>')
def profile(username):
return f'User: {username}'
# HTTP 方法
@app.route('/submit', methods=['GET', 'POST'])
def submit():
if request.method == 'POST':
return 'Posted!'
return 'Form'
模板渲染(Jinja2)
from flask import render_template, request
@app.route('/')
def index():
articles = [
{'title': 'Flask 入门', 'views': 100},
{'title': 'Django vs Flask', 'views': 200},
]
return render_template('index.html', articles=articles, title='首页')
<!-- templates/index.html -->
<!DOCTYPE html>
<html>
<head><title>{{ title }}</title></head>
<body>
<h1>{{ title }}</h1>
{% for article in articles %}
<article>
<h2>{{ article.title }}</h2>
<span>阅读: {{ article.views }}</span>
</article>
{% endfor %}
</body>
</html>
Jinja2 常用语法
{# 注释 #}
{{ variable }}
{{ variable|default('默认值') }}
{{ variable|length }}
{{ "%.2f"|format(3.14159) }}
{% if user.is_admin %}
管理员面板
{% elif user.is_active %}
欢迎回来
{% else %}
请登录
{% endif %}
{% for item in items %}{{ item }}{% endfor %}
{% macro render_field(field) %}
{{ field.label }} {{ field(**kwargs) }}
{% endmacro %}
WTForms 表单验证
pip install flask-wtf
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, Length
class LoginForm(FlaskForm):
username = StringField('用户名', validators=[DataRequired(), Length(3, 20)])
password = PasswordField('密码', validators=[DataRequired()])
submit = SubmitField('登录')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.check_password(form.password.data):
login_user(user)
return redirect(url_for('dashboard'))
return render_template('login.html', form=form)
<form method="post">
{{ form.hidden_tag() }}
{{ form.username.label }} {{ form.username() }}
{{ form.password.label }} {{ form.password() }}
{{ form.submit() }}
</form>
SQLAlchemy ORM
pip install flask-sqlalchemy
from flask_sqlalchemy import SQLAlchemy
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
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))
content = db.Column(db.Text)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
created_at = db.Column(db.DateTime, default=db.func.now())
# 查询
users = User.query.filter_by(username='张三').first()
user_posts = Post.query.filter_by(user_id=user.id).order_by(Post.created_at.desc()).all()
蓝图(模块化)
# apps/auth.py
from flask import Blueprint
bp = Blueprint('auth', __name__, url_prefix='/auth')
@bp.route('/login')
def login(): return 'Login'
@bp.route('/logout')
def logout(): return 'Logout'
# app.py 注册
from apps.auth import bp as auth_bp
app.register_blueprint(auth_bp)
REST API
from flask import jsonify
@app.route('/api/posts')
def get_posts():
posts = Post.query.order_by(Post.created_at.desc()).limit(20).all()
return jsonify([{
'id': p.id,
'title': p.title,
'content': p.content,
'author': p.author.username,
'created_at': p.created_at.isoformat()
} for p in posts])
常见问题
Q1: Flask 跟 Django 怎么选?Flask 更轻量灵活,适合 API 和小项目。Django 全功能自带 ORM/Admin,适合企业应用。
Q2: 如何处理文件上传?from flask import request; file = request.files['file']; file.save('uploads/' + file.filename)。
Q3: Flask-SQLAlchemy 怎么防止 SQL 注入?SQLAlchemy 自动参数化查询,不用担心 SQL 注入。
延伸阅读
- Flask-RESTful 快速 API 开发
- Flask 单元测试
- Flask + Docker 部署
---
作者:小马 | 绍大技术网 shaoda.net