目录
一、Flask 框架概述
1、安装 Flask
2、创建一个Flask 应用
3、运行Flask应用
二、Flask 路由与视图函数
1、动态路由
2、支持多种HTTP请求方法
3、使用Jinja2 模板渲染HTML
4、模板继承与块
三、Flask 表单处理与用户输入
1、安装Flask-WTF
2、创建一个简单的表单
3、表单验证
四、Flask 的项目结构与部署
1、项目结构
2、部署Flask应用
Flask 作为一个微框架,强调简单性和灵活性。它依赖于两个重要的 Python 库来提供核心功能:
- Werkzeug:这是 Flask 的底层库,提供了 WSGI 接口、HTTP 请求和响应处理、路由等核心功能。
- Jinja2:一个功能强大的模板引擎,用于动态生成 HTML 页面。
Flask 的设计目的是让开发者能够快速开发应用,并提供了灵活的方式进行扩展。如果你不需要复杂的功能,Flask 的核心本身已经足够满足需求。如果你需要更多高级特性,可以通过 Flask的扩展库进行补充。
安装 Flask 非常简单,只需使用 Python 的包管理工具 pip 即可:
pip3 config set global.index-url http://mirrors.aliyun.com/pypi/simple
pip3 config set install.trusted-host mirrors.aliyun.com/pypi/simple
pip3 install --upgrade pip
pip3 install flask
安装完成后,你可以通过创建一个简单的Flask 应用来验证是否安装成功。
systemctl stop firewalld
#关闭防火墙
Flask 的应用结构非常简单,只需创建一个 Python 文件,并通过 Flask()类来实例化应用对象。以下是一个最简单的 Flask 应用示例:
vim aaa.py
from flask import Flask
#创建Flask应用实例
app=Flask(__name__)
#定义路由和视图函数
@app.route('/')
def hello_world():
return 'Hello,World!\n'
#启动应用
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=True)
- Flask(__name__ ):创建 Flask 应用实例,__name__参数用于 Flask 了解当前模块的名称,通常我们使用这个参数来帮助 Flask 在不同模块间进行配置。
- @app.route('/'):定义路由和视图函数的映射。'/'是根路径,当用户访问根 URL 时,Flask会调用 hello world()函数。
- return 'Hello,world!':视图函数返回一个简单的字符串响应,Flask 会将其作为 HTTP 响应返回给客户端。
- app.run(debug=True):启动 Flask 开发服务器,debug=True 表示启用调试模式,这样可以在开发过程中自动重载应用,并在发生错误时显示详细信息。
保存上述代码为aaa.py,然后在命令行中运行:
python3 aaa.py
这时 Flask 会启动一个开发服务器,默认会监听 0.0.0.0:5000(所有ip)。打开浏览器,访问http://192.168.10.101:5000/,会看到“Hello,World!”的页面。
Flask 的核心之一就是路由系统,它将用户访问的 URL 与对应的视图函数相连接。Flask 通过装饰器@app.route()来定义路由,而视图函数则负责处理用户的请求并返回响应。
Flask 支持动态路由参数,可以通过 URL 中的动态部分来获取数据。以下是一个示例:
vim aaa.py
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello,World!\n'
@app.route('/greet/')
def greet(name):
return f'ni hao,{name}\n'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=True)
:这是一个动态路由参数,Flask 会提取 URL 中的 name 部分并将其传递给视图函数。 - 若用户访问192.168.10.101:5000/greet/zhangsan,name 的值将为 zhangsan,返回的响应为ni hao,zhangsan!。
Flask 不仅支持 GET 请求,还支持其他常见的 HTTP 请求方法,如 POST、PUT、DELETE 等。你可以通过methods 参数来指定允许的请求方法:
vim aaa.py
from flask import Flask
app=Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello,World!\n'
@app.route('/greet/')
def greet(name):
return f'ni hao,{name}\n'
@app.route('/submit',methods=['POST'])
def submit():
return '提交成功\n'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=True)
- methods=['POST']:只允许 POST 请求访问此路由。如果用户通过 GET 请求访问,Flask 会返回405 Method Not Allowed 错误。
Flask 结合 Jinja2 模板引擎来动态生成 HTML 页面。可以将 HTML 文件与 Python 代码分离,保持应用结构清晰。在 Flask 中,模板文件默认存放在 templates 文件夹中。
mkdir templates
在templates下创建一个名为 greet.html 的模板文件,内容如下:
ni hao,zhangsan
hello,{{ name }}
在 Flask 应用中,我们可以通过 render_template 函数渲染模板并传递动态数据:
vim aaa.py
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello,World!\n'
@app.route('/greet/')
def greet(name):
return render_template('greet.html',name=name)
@app.route('/submit',methods=['POST'])
def submit():
return '提交成功\n'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=True)
render_template('greet.html',name=name):Flask会加载greet.html模板,并将name的值传递给模板。模板中的{{ name }}会被替换为传入的值。
Flask 支持模板继承和块(Block)功能,这对于构建复杂页面非常有用。你可以在基础模板中定义通用的布局结构,在子模板中覆盖特定的部分。
基础模板base.html:
vim templates/index.html
{% block title %}My website{% endblock %}
欢迎
{% block content %}zhangsan{% endblock %}
子模版index.html:
vim templates/index.html
{% extends 'base.html' %}
{% block title %}zhangsan{% endblock %}
{% block content %}
ni hao lisi
{% endblock %}
- {% extends'base.html'%}:子模板继承了 base.html 模板。
- {% block title %}Home{% endblock %}:覆盖父模板中的 title 块。
- {% block content %}:定义页面的主要内容区域。
vim aaa.py
from flask import Flask,render_template
app=Flask(__name__)
@app.route('/')
def aaa():
return render_template('index.html')
@app.route('/greet/')
def greet(name):
return render_template('greet.html',name=name)
@app.route('/submit',methods=['POST'])
def submit():
return '提交成功\n'
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=True)
Flask 可以通过表单来获取用户输入,常见的做法是结合 Flask-WTF 扩展来简化表单处理和验证。
Flask-WTF为Flask 提供了一个表单类,你可以在表单类中定义字段和验证规则。
pip install flask-wtf
vim biaodan.py
from flask import Flask, render_template, request
from flask_wtf import FlaskForm
from wtforms import StringField
from wtforms.validators import DataRequired
app = Flask(__name__)
app.secret_key = 's3cr3t'
class NameForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
return f'Hello, {form.name.data}!'
return render_template('index.html', form=form)
if __name__ == '__main__':
#app.run(debug=True)
app.run(host='0.0.0.0', port=5000, debug=True)
- FlaskForm:继承自FlaskForm 类,定义表单字段。
- StringField('Name',validators=[DataRequired()]):定义了一个文本输入字段,并且通过 DataRequired()验证器确保字段不能为空。
- form.validate_on_submit():检査表单是否通过验证并被提交。
templates目录下的index.html 模板:
Flask Form
Enter your name:
{% if form.name.data %}
Hello, {{ form.name.data }}!
{% endif %}
- {{ form.csrf_token }}:Flask-WTF会自动生成并验证 CSRF token,以防止跨站请求伪造攻击。
- {{ form.name() }}:这是通过 Jinja2 模板渲染 NameForm 表单的字段。form.name()会生成对应的 HTML 标签。
- {% if form.name.data %}:如果用户提交了表单并且 name 字段不为空,则显示欢迎信息
Flask 表单处理的强大之处在于它的验证机制。通过wtforms,你可以非常方便地为表单字段添加各种验证规则。比如,除了 DataRequired(),你还可以使用:
- Length(min=2,max=50):验证输入的长度。
- Email():验证输入是否是有效的邮箱地址。
- EqualTo('password'):验证两个字段的值是否相等。
随着应用的复杂度增加,Flask应用的结构通常会发生变化。一个典型的Flask项目结构如下:
/my_flask_app
/app
/templates
index.html
/static
/css
/js
__init__·py
routes.py
forms.py
run.py
- /templates:存放所有 HTML 模板文件。
- /static:存放静态文件(如CSS、JS、图片等)
- __init__.py:初始化 Flask 应用
- routes.py:定义所有路由和视图函数。
- forms.py:定义表单类
Flask 应用的开发环境通常使用 Flask run 启动,但在生产环境中,我们需要通过更强大的 web 服务器进行部署,常见的有:
- Gunicorn:一个Python WSGI HTTP 服务器,常用于生产环境部署。
- Nginx:作为反向代理,前端处理静态文件请求,转发动态请求到Flask应用
部署时,可以通过以下命令启动 Flask 应用:
gunicorn -w 4 run:app
这将启动一个4 工作线程的 Gunicorn 服务器,run 是指向 Flask 应用实例的模块。