一、起步
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!'
该程序会启动一个Flask Web应用,并在默认端口 (http://localhost:5000/) 上监听来自客户端的请求。当我们在浏览器中访问 http://localhost:5000/ 时,程序将返回"Hello, World!"。
二、URL路由与视图函数
1、Flask中URL路由的基本定义
路由是指当Web服务器接到一个客户端请求时,需要将请求指向哪个视图函数的一条映射规则。Flask中,我们可以使用 @app.route() 装饰器来对指定的 URL 进行绑定。例如,我们可以编写以下代码实现访问 http://localhost:5000/hello/ 返回"Hello!"的功能:from flask import Flask
app = Flask(__name__)
@app.route('/hello/')
def hello():
return "Hello!"
2、使用变量规则
你可以通过使用from flask import Flask
app = Flask(__name__)
@app.route('/user/
')
def user(name):
return f"Hello, {name}!"
三、模板
1、模板的作用与用途
在Web应用程序中,模板通常指的是一种HTML文件,用于将动态数据渲染到用户端浏览器中。Flask可以使用 Jinja2 模板引擎来创建模板。Flask严格遵循MVC(Model-View-Controller)模式来构建Web应用程序,而Jinja2模板引擎也正是属于其中的"视图"部分。2、使用模板渲染动态数据
Flask在使用Jinja2模板引擎前,需要先指定好模板的文件夹位置。通常,我们使用 Flask 的构造函数中的 template_folder 参数来指定模板文件所在的目录:from flask import Flask, render_template
app = Flask(__name__, template_folder='templates')
@app.route('/user/
')
def user(name):
return render_template('user.html', name=name)
接下来,我们可以在模板文件中渲染动态数据:
<html>
<head>
<title>User page</title>
</head>
<body>
Hello, {{ name }}!
</body>
</html>
四、表单
1、用法与作用
表单是Web应用程序中收集用户输入的一种HTML元素。在Flask中,我们可以使用Werkzeug的Request对象来获取表单数据。对于GET请求,数据会出现在URL查询字符串中(例如http://localhost:5000/login?username=test&password=123),而POST请求则需要从Request对象中获取。2、处理POST请求
以下是一个简单的处理POST请求的程序:from flask import Flask, request
app = Flask(__name__)
@app.route('/login', methods=['POST'])
def do_login():
username = request.form['username']
password = request.form['password']
if username == 'admin' and password == 'admin':
return f"Hello, {username}!"
else:
return "Invalid login credentials!"
五、ORM
1、Flask_SQLAlchemy
ORM(Object Relation Mapping,对象关系映射)是一种技术,它把数据库中的表格映射到了程序中的对象上。在Flask中,我们可以使用Flask_SQLAlchemy库来进行ORM操作。Flask_SQLAlchemy库是在SQLAlchemy库的基础上,增加了Flask特有的一些功能。以下是一个简单的示例程序:from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.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"User {self.username}, {self.email}"
2、使用ORM查询数据
以下代码是如何使用ORM查询User表格中的数据:users = User.query.all()
user = User.query.filter_by(username='admin').first()
六、插件
1、Flask插件介绍
除了jinja2和Werkzeug之外,Flask还提供了大量的扩展,它们可以帮助开发者快速地实现某些功能。例如, Flask-Moment 是一个支持本地化时间的插件, Flask-Misaka 是一个为Markdown提供支持的插件, Flask-Mail 是一个用于发送邮件的插件。Flask插件的安装方式也很简单:$ pip install flask-moment
2、Flask-Moment插件使用示例
以下代码展示如何在Jinja2模板中使用Flask-Moment插件:<html>
<head>
...
{{ moment.include_moment() }}
</head>
<body>
...
The current date and time is: {{ moment(format='LLLL') }}
</body>
</html>
七、RESTful API
1、什么是RESTful API
RESTful API是一种能够使用HTTP请求(GET、POST、PUT、DELETE等)实现对Web资源进行操作的API。与传统的WebService不同,RESTful API并不依赖于XML、SOAP等传输格式,而是通过自描述的JSON格式进行数据传输和交互。2、使用Flask-RESTful实现RESTful API
Flask-RESTful是基于Flask扩展的库,旨在帮助开发人员方便地编写REST APIs。以下代码展示了如何使用Flask-RESTful实现一个返回当前时间的API:from flask import Flask
from flask_restful import Resource, Api
app = Flask(__name__)
api = Api(app)
class CurrentTime(Resource):
def get(self):
return {'time': datetime.datetime.now()}
api.add_resource(CurrentTime, '/time')
if __name__ == '__main__':
app.run(debug=True)
八、WebSocket
1、什么是WebSocket
WebSocket是一种协议,允许服务器与客户端进行双向通信。相比于HTTP协议,它能够更加快速地进行数据交互并小幅度减少网络流量。2、使用Flask-SocketIO实现WebSocket
Flask-SocketIO是一个在Flask上实现WebSocket的扩展库。以下代码展示了如何使用Flask-SocketIO实现一个简单的聊天室程序:from flask import Flask, render_template
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@app.route('/')
def index():
return render_template('index.html')
@socketio.on('message')
def handle_message(message):
emit('response', message, broadcast=True)
if __name__ == '__main__':
socketio.run(app)
九、分页
1、处理分页请求
在Web应用程序中,分页通常用来将用户请求的数据分成若干个页面来显示。Flask框架提供了一个常用的分页扩展:Flask-Paginate。向用户返回分页数据时,我们需要对用户请求进行解析。以下代码展示了如何处理分页请求:from flask_paginate import Pagination
@app.route('/paginate')
def paginate():
total = 500
page = request.args.get('page', 1, type=int)
per_page = request.args.get('per_page', 10, type=int)
pagination = Pagination(
page=page,
per_page=per_page,
total=total,
css_framework='bootstrap4',
)
return render_template('paginate.html', items=range(total), pagination=pagination)
2、在模板中渲染分页数据
使用Flask-Paginate渲染分页数据也非常简单。在 Flask-Paginate 中,我们需要使用 Pagination 类来定义页面参数,例如:当前页面号、每页显示条目的数量和页数。我们还需要使用 render_template() 方法将查询结果封装成页面,然后将参数传递到模板中以进行呈现:{% extends 'base.html' %}
{% block content %}
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
{{ pagination.links }}
{% endblock %}
十、安全
1、Flask-Security
Web应用程序的安全性非常重要,Flask-Security是Flask扩展库中提供的一种安全增强工具,其支持用户认证、密码加密等功能。Flask-Security 解决了实现 Flask 应用时许多常见的安全问题。以下是一个使用 Flask-Security 的示例程序:from flask import Flask
from flask_security import Security, \
SQLAlchemyUserDatastore, UserMixin, RoleMixin
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/myapp.db'
app.config['SECRET_KEY'] = 'super-secret'
app.config['SECURITY_PASSWORD_HASH'] = 'bcrypt'
app.config['SECURITY_PASSWORD_SALT'] = 'salt'
db = SQLAlchemy(app)
roles_users = db.Table('roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(255), unique=True)
password = db.Column(db.String(255))
active = db.Column(db.Boolean())
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), unique=True)
description = db.Column(db.String(255))
user_datastore = SQLAlchemyUserDatastore(db, User, Role)
security = Security(app, user_datastore)
2、CSRF防护
跨站点请求伪造(CSRF)是一种攻击方式,它利用Web应用程序已通过认证的用户身份,在不知情的情况下执行非预期的动作。通过发送带有 CSRF 令牌的 POST / PUT / DELETE 请求,我们可以快速在 Flask 应用