Python Web开发:Flask框架入门
Python Web开发:Flask框架入门一、Flask简介Flask是一个轻量级的Python Web框架,遵循WSGI规范。1.1 Flask的特点- 轻量级,核心简单- 灵活,可扩展性强- 内置开发服务器和调试器- RESTful请求分发- Jinja2模板引擎- 支持单元测试1.2 安装Flask二、第一个Flask应用# 运行: python app.py。
·
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
6.2 模板语法
# 变量
{{ variable }}
# 控制结构
{% if user %}
{% else %}
{% endif %}
# 循环
{% for item in items %}
{% block head %}
{% block title %}{% endblock %}
{% endblock %}
{% block content %}{% endblock %}
# child.html
{% extends "base.html" %}
{% block title %}Home{% endblock %}
{% block content %}
{% 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开发的热门选择。
一、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, {{ name }}!
6.2 模板语法
# 变量
{{ variable }}
# 控制结构
{% if user %}
Hello, {{ user }}!
{% else %}
Hello, Guest!
{% endif %}
# 循环
{% for item in items %}
- {{ item }}
{% endfor %}
# 模板继承
# base.html
{% block head %}
{% 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开发的热门选择。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)