Python Web开发:Flask框架入门

一、Flask简介

Flask是一个轻量级的Python Web框架,遵循WSGI规范。

1.1 Flask的特点

- 轻量级,核心简单
- 灵活,可扩展性强
- 内置开发服务器和调试器
- RESTful请求分发
- Jinja2模板引擎
- 支持单元测试

1.2 安装Flask

pip install flask

二、第一个Flask应用

2.1 Hello World

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
return 'Hello, World!'

if __name__ == '__main__':
app.run(debug=True)

# 运行: python app.py
# 访问: http://localhost:5000

2.2 路由和视图函数

@app.route('/user/')
def show_user(username):
return f'User: {username}'

@app.route('/post/')
def show_post(post_id):
return f'Post ID: {post_id}'

# URL转换器
# string: 默认,接受任何不包含斜杠的文本
# int: 接受整数
# float: 接受浮点数
# path: 类似string,但接受斜杠
# uuid: 接受UUID字符串

三、HTTP方法

3.1 处理不同的HTTP方法

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
# 处理登录逻辑
return f'Logging in {username}'
else:
# 显示登录表单
return '''





'''

3.2 RESTful API

@app.route('/api/users', methods=['GET'])
def get_users():
return {'users': ['Alice', 'Bob']}

@app.route('/api/users', methods=['POST'])
def create_user():
data = request.get_json()
return {'message': 'User created', 'user': data}, 201

@app.route('/api/users/', methods=['PUT'])
def update_user(user_id):
data = request.get_json()
return {'message': f'User {user_id} updated'}

@app.route('/api/users/', methods=['DELETE'])
def delete_user(user_id):
return {'message': f'User {user_id} deleted'}

四、请求对象

4.1 访问请求数据

from flask import request

@app.route('/search')
def search():
# 查询参数
query = request.args.get('q', '')

# 表单数据
username = request.form.get('username')

# JSON数据
data = request.get_json()

# 文件上传
file = request.files.get('file')

# 请求头
user_agent = request.headers.get('User-Agent')

# Cookie
session_id = request.cookies.get('session_id')

return f'Search: {query}'

五、响应对象

5.1 返回不同类型的响应

from flask import jsonify, make_response, redirect, url_for

# 返回JSON
@app.route('/api/data')
def get_data():
return jsonify({'key': 'value'})

# 自定义响应
@app.route('/custom')
def custom_response():
response = make_response('Custom response')
response.headers['X-Custom-Header'] = 'Value'
response.status_code = 200
return response

# 重定向
@app.route('/old-url')
def old_url():
return redirect(url_for('new_url'))

@app.route('/new-url')
def new_url():
return 'New URL'

# 设置Cookie
@app.route('/set-cookie')
def set_cookie():
response = make_response('Cookie set')
response.set_cookie('username', 'Alice')
return response

六、模板渲染

6.1 使用Jinja2模板

from flask import render_template

@app.route('/hello/')
def hello_template(name):
return render_template('hello.html', name=name)

# templates/hello.html



Hello


Hello, {{ name }}!





6.2 模板语法

# 变量
{{ variable }}

# 控制结构
{% if user %}

Hello, {{ user }}!


{% else %}

Hello, Guest!


{% endif %}

# 循环
{% for item in items %}
  • {{ item }}

  • {% endfor %}

    # 模板继承
    # base.html



{% block head %}
{% block title %}{% endblock %}
{% endblock %}


{% block content %}{% endblock %}



# child.html
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}

Welcome


{% endblock %}

七、静态文件

7.1 提供静态文件

# 目录结构
myapp/
├── app.py
├── static/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
└── templates/

# 在模板中引用
rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
<script src="%7b%7b%20url_for%28'static',%20filename='js/script.js'%29%20%7d%7d"></script>


八、会话管理

8.1 使用Session

from flask import session

app.secret_key = 'your-secret-key-here'

@app.route('/login', methods=['POST'])
def login():
session['username'] = request.form['username']
return redirect(url_for('index'))

@app.route('/logout')
def logout():
session.pop('username', None)
return redirect(url_for('index'))

@app.route('/')
def index():
if 'username' in session:
return f'Logged in as {session["username"]}'
return 'Not logged in'

九、错误处理

9.1 自定义错误页面

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

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

# 手动触发错误
from flask import abort

@app.route('/admin')
def admin():
if not is_admin():
abort(403)
return 'Admin page'

十、蓝图(Blueprints)

10.1 使用蓝图组织代码

# auth.py
from flask import Blueprint

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

@auth_bp.route('/login')
def login():
return 'Login page'

@auth_bp.route('/logout')
def logout():
return 'Logout'

# app.py
from flask import Flask
from auth import auth_bp

app = Flask(__name__)
app.register_blueprint(auth_bp)

# 访问: /auth/login, /auth/logout

十一、数据库集成

11.1 使用Flask-SQLAlchemy

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///app.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)
email = db.Column(db.String(120), unique=True, nullable=False)

def __repr__(self):
return f''

# 创建表
with app.app_context():
db.create_all()

# CRUD操作
@app.route('/users', methods=['POST'])
def create_user():
data = request.get_json()
user = User(username=data['username'], email=data['email'])
db.session.add(user)
db.session.commit()
return {'id': user.id}, 201

@app.route('/users/')
def get_user(user_id):
user = User.query.get_or_404(user_id)
return {'username': user.username, 'email': user.email}

十二、表单处理

12.1 使用Flask-WTF

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email

class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')

@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
username = form.username.data
password = form.password.data
# 处理登录
return redirect(url_for('index'))
return render_template('login.html', form=form)

十三、中间件和钩子

13.1 请求钩子

@app.before_request
def before_request():
# 在每个请求之前执行
print('Before request')

@app.after_request
def after_request(response):
# 在每个请求之后执行
response.headers['X-Custom-Header'] = 'Value'
return response

@app.teardown_request
def teardown_request(exception):
# 请求结束时执行(即使发生异常)
if exception:
print(f'Exception: {exception}')

十四、配置管理

14.1 配置方式

# 方式1:直接设置
app.config['DEBUG'] = True
app.config['SECRET_KEY'] = 'your-secret-key'

# 方式2:从对象加载
class Config:
DEBUG = False
TESTING = False
SECRET_KEY = 'your-secret-key'

class DevelopmentConfig(Config):
DEBUG = True

app.config.from_object(DevelopmentConfig)

# 方式3:从文件加载
# config.py
DEBUG = True
SECRET_KEY = 'your-secret-key'

app.config.from_pyfile('config.py')

# 方式4:从环境变量
app.config.from_envvar('APP_CONFIG_FILE')

十五、日志配置

import logging
from logging.handlers import RotatingFileHandler

if not app.debug:
handler = RotatingFileHandler('app.log', maxBytes=10000, backupCount=3)
handler.setLevel(logging.INFO)
app.logger.addHandler(handler)

app.logger.info('Application started')

十六、部署

16.1 使用Gunicorn

# 安装
pip install gunicorn

# 运行
gunicorn -w 4 -b 0.0.0.0:8000 app:app

16.2 使用uWSGI

# 安装
pip install uwsgi

# 运行
uwsgi --http :8000 --wsgi-file app.py --callable app

十七、最佳实践

1. 使用蓝图组织大型应用
2. 使用配置对象管理不同环境
3. 使用Flask-SQLAlchemy管理数据库
4. 使用Flask-WTF处理表单
5. 使用Flask-Login管理用户认证
6. 使用Flask-Migrate管理数据库迁移
7. 使用环境变量存储敏感信息
8. 启用CSRF保护
9. 使用HTTPS
10. 配置适当的日志级别

十八、总结

Flask是一个灵活而强大的Web框架,适合从小型项目到大型应用的开发。通过掌握路由、模板、数据库集成等核心概念,以及使用蓝图、扩展等高级特性,可以高效地构建Web应用。Flask的简洁设计和丰富的扩展生态使其成为Python Web开发的热门选择。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐