Flask应用的基本组成部分包括路由、视图函数、请求和响应。
路由(Routing)是将URL映射到相应的视图函数(View Function)上的过程。
在Flask中,可以通过装饰器来定义路由,如下所示:
from flask import Flaskapp = Flask(__name__) # 实例化一个Flask对象,最基本的写法@app.route('/')
def index():return 'Hello, World!'if __name__ == "__main__":app.run()
在Python中,装饰器(decorator)是一种特殊的函数,用于修改或增强其他函数的功能。装饰器是通过在被装饰函数的定义前加上
@
符号,将被装饰函数传递给装饰器函数作为参数来实现的。
在上面的代码中,我们通过app.route
装饰器定义了一个路由,将/
映射到index
函数上。当用户在浏览器中访问/
时,就会执行index
函数,并返回'Hello, World!'
这个字符串。
上面的例子中,index
函数就是一个视图函数。
Flask应用中处理请求并返回响应的函数。视图函数通常会接收一些参数(如URL中的参数、POST请求中的表单数据等),并根据这些参数进行处理,最后返回一个响应(如HTML页面、JSON数据等)。
请求是Flask应用中接收客户端发来的数据的对象。
每次客户端发送一个HTTP请求时,Flask将会创建一个request
对象。
在视图函数中,我们可以通过request
对象获取客户端提交的数据(如表单数据、URL 参数等)。例如,下面的代码中,我们通过request.args.get
方法获取了URL参数中的name
参数:
from flask import Flask, requestapp = Flask(__name__)@app.route('/')
def index():name = request.args.get('name', 'World')return f'Hello, {name}!'
在浏览器中访问/?name=Flask
,就会返回'Hello, Flask!'
这个字符串。
下面是request一些常用的方法和属性:
request.method
:HTTP请求方法,如 GET、POST、PUT、DELETE 等。request.args
:获取查询参数,返回一个不可变字典。request.form
:获取表单参数,返回一个不可变字典。request.files
:获取上传的文件,返回一个不可变字典。request.headers
:获取请求头,返回一个字典。request.cookies
:获取请求中的 cookies,返回一个字典。request.remote_addr
:获取客户端的 IP 地址。request.path
:获取请求路径,不包含查询参数。request.url
:获取完整的请求 URL。request.is_xhr
:判断请求是否是 AJAX 请求。提取方法 | 描述 |
---|---|
request.cookies | 提取cookie字典信息 |
request.args.get(“name”) | 查询字符串参数 /user?name=curry&age=18 |
request.form.get(“name”) | 表单数据 {“name”: “james”, “age”: 38} |
request.json.get(“name”) | json格式字符串参数 |
参考连接:http://t.csdn.cn/kFwUR
响应是Flask应用中返回给客户端的数据。
在视图函数中,我们可以通过return
语句返回响应。
响应可以是各种格式的数据,如HTML页面、JSON数据、图片、文件等。例如,下面的代码中,我们返回了一个HTML页面:
from flask import Flaskapp = Flask(__name__)@app.route('/')
def index():return 'Hello, World!
'
在浏览器中访问 /
,就会显示一个标题为'Hello, World!'
的 HTML 页面。
在Flask中,我们可以使用make_response()
函数来创建一个响应对象,并可以通过设置其内容、状态码、头部等属性来进行自定义。
例如,以下代码定义了一个包含自定义内容和状态码的响应:
from flask import Flask, make_responseapp = Flask(__name__)@app.route('/')
def hello_world():response = make_response('Hello World!', 200)# 这里设置了一个自定义的响应头,键为 'X-My-Header',值为 'my-value'response.headers['X-My-Header'] = 'my-value'return response
下面是response一些常用的方法和属性:
response.status_code
:HTTP 响应状态码,如 200、404 等。response.headers
:HTTP 响应头,可以通过该属性设置自定义的响应头,返回一个字典。response.content_type
:HTTP 响应内容的 MIME 类型,如 text/html、application/json 等。response.data
:HTTP 响应内容,返回一个字节串。response.set_cookie()
:设置 cookie。response.delete_cookie()
:删除 cookie。response.make_response()
:创建一个 Response 对象,可以通过该方法自定义响应内容和响应头。官网地址:https://flask.palletsprojects.com/en/latest/
Jinja2中文文档_w3cschool
Jinja2是Flask默认的模板引擎,它是一种基于Python语言的模板引擎,具有简单、高效、安全等特点。
Jinja2支持模板继承、变量替换、条件判断、循环遍历等常用的模板操作。
在Flask中,我们可以通过在应用程序中配置模板路径,然后在视图函数中使用render_template
函数来渲染模板,将动态数据和静态内容结合起来,最终生成一个完整的HTML页面。
来看一个例子,演示如何在Flask应用中使用Jinja2模板引擎:
# app.py
from flask import Flask, render_templateapp = Flask(__name__)
app.config['TEMPLATES_AUTO_RELOAD'] = True # 设置模板自动重载@app.route('/')
def index():return render_template('index.html', name='John Doe')
我们在Flask应用的根目录下创建一个templates
文件夹,并在该文件夹下创建一个名为 index.html
的模板文件。在该模板文件中,我们可以使用Jinja2提供的语法来渲染动态数据和静态内容。
以下是一个简单的 index.html
模板文件的示例:
{{ name }} - My Flask App Hello, {{ name }}!
{{ name }}
:表示要渲染的动态数据,其中 name
是我们在视图函数中传递给模板的参数。最后,我们可以通过访问 http://localhost:5000/
来查看渲染后的页面效果,页面将会显示 Hello, John Doe!
。
注意:
app.config['TEMPLATES_AUTO_RELOAD'] = True
是 Flask 应用中配置模板自动重载的参数。如果将其设置为 True,则在修改模板文件后,Flask 会自动重载模板,从而使得修改后的模板能够生效。这在开发阶段非常有用,因为可以避免每次修改模板后都需要手动重启应用的麻烦。csdn链接:http://t.csdn.cn/ENFfK
{% if condition %}条件为真
{% elif other_condition %}其他条件为真
{% else %}所有条件都为假
{% endif %}
{% for item in items %}{{ item }}
{% else %}列表为空
{% endfor %}
过滤器可以用管道符|
链接到变量之后。
例如,我们有一个变量name
,我们可以使用capitalize
过滤器将它的第一个字母大写:
{{ name | capitalize }}
还可以使用多个过滤器,其中每个过滤器的输出作为下一个过滤器的输入,如下所示:
{{ name | lower | replace(" ", "_") }}
上面把变量name
中的所有字母都转换为小写,并将空格替换为下划线。
Jinja2中的常见过滤器包括:
safe
: 标记值为安全,将不进行转义capitalize
: 将字符串的第一个字符大写lower
: 将字符串转换为小写upper
: 将字符串转换为大写title
: 将字符串的每个单词的首字母大写trim
: 删除字符串开头和结尾的空白字符replace
: 将字符串中的某个子串替换为另一个字符串宏是 Jinja2 中可重用的代码块,可以在模板的任何地方调用。
通过使用 Jinja2 中的 {% macro %}
标签定义宏,然后可以在模板的任何地方调用它。例如:
{% macro hello(name) %}Hello, {{ name }}!
{% endmacro %}
这个宏定义了一个 hello
的宏,它接受一个名为 name
的参数,并返回一个带有 name
的 h1
标签。假设该宏在一个名为 hello_macro.html
的模板文件。
接下来,我们在另一个模板文件中使用这个宏。内容如下:
{% import 'hello_macro.html' as macros %}{{ macros.hello('World') }}
这个文件中首先使用了 import
指令将 hello_macro.html
中的宏导入,并定义了一个名为 macros
的命名空间来包含这个宏。然后,我们就可以在文件中使用这个宏了。
最终生成的 HTML 代码将是:
Hello, World!
如果是在同一文件调用:
{{ hello('World') }}
下面是一个相对复杂的例子:
{% macro render_person(person) %}{{ person.name }}
Age: {{ person.age }}
{% if person.email %}Email: {{ person.email }}
{% endif %}
{% endmacro %}{% for person in people %}{{ render_person(person) }}
{% endfor %}
render_person
的宏,用于渲染一个人的信息。person
对象作为参数,并使用该对象的属性来渲染 HTML。for
循环来遍历人的列表,并使用 render_person
宏来渲染每个人的信息。
{% with title="Hello, World!" %}{{ title }}
{% endwith %}{% with total = 1 + 2 %}{{ total }}
{% endwith %}
使用with
定义的变量作用范围在{% with %}
和{% endwith %}
之间。
还可以使用set
定义临时变量:
{% set x = 1 %}
{% if x %}{% set y = 2 %}
{% endif %}{{ x }} # 输出 1
{{ y }} # 报错,y未定义
set
的作用范围是定义它的块级范围,块级范围内的变量名只在该块级范围内有效,出了这个范围,这个变量名就失效了。
在这个例子中,{% set x = 1 %}
定义了变量 x
,作用范围为整个模板。在 if
语句中,当 x
的值为真时,{% set y = 2 %}
定义了变量 y
,作用范围为 if
语句块级范围。因此,当 if
语句的条件为假时,变量 y
未被定义,因此输出时会报错。
宏和临时变量:
在 Flask 中,可以通过定义基础模板和扩展模板来实现代码的复用和管理,使得代码更加简洁和易于维护。
定义基础模板可以使用 {% block %}
和 {% endblock %}
标签,其中 {% block %}
定义了一个块,其内容可以被子模板继承和覆盖。
在子模板中可以使用 {% extends %}
标签继承基础模板,同时通过 {% block %}
标签覆盖父模板中定义的块。
举个例子,假设我们有一个父模板 base.html
,它包含了一个名为 content
的块。现在我们想要创建一个子模板 child.html
,它继承自父模板并重写 content
块,可以这样实现:
{% block title %}{% endblock %} {% block content %}{% endblock %}
{% extends "base.html" %}{% block title %}Child Template{% endblock %}{% block content %}Hello, World!
{% endblock %}
在子模板中:
{% extends "base.html" %}
声明了它继承自 base.html
{% block ... %} ... {% endblock %}
块声明了要重写的内容。child.html
就拥有了 base.html
中的所有内容,并且可以根据自己的需求覆盖 base.html
中的块内容。base.html
,然后替换其中的 content
块为子模板 child.html
中定义的内容。FlaskForm
类的类来实现的。这个类中定义了表单中各个字段的类型、标签、验证规则等信息。form
对象可以在模板中生成表单,并通过 validate_on_submit()
方法对表单数据进行验证和处理。pip install Flask-WTF
在 Flask 中定义表单类可以使用 Flask-WTF 扩展中的 FlaskForm
类,也可以使用 WTForms 库中的 Form
类。后面主要以使用 FlaskForm
为例。
每个表单字段都是一个实例变量,可以设置不同的参数,如字段类型、标签、验证规则等。
例如,如果需要使用字符串类型字段和数据验证器,可以这样定义表单类:
from flask_wtf import FlaskForm
from wtforms import StringField, validatorsclass MyForm(FlaskForm):name = StringField('Name', validators=[validators.DataRequired()])
在上面的代码中,定义了一个名为 MyForm
的表单类,其中包含一个字符串类型的 name
字段,该字段使用了 DataRequired
验证器,用于验证该字段的值是否为空。
常用的字段类型:
字段类型 | 描述 |
---|---|
StringField | 字符串字段,用于接受字符串类型的数据 |
IntegerField | 整型字段,用于接受整数类型的数据 |
DecimalField | 十进制浮点型字段,用于接受浮点型数据,可以指定精度 |
BooleanField | 布尔型字段,用于接受 True 或 False 类型的数据 |
DateField | 日期型字段,用于接受日期类型的数据 |
TimeField | 时间型字段,用于接受时间类型的数据 |
DateTimeField | 日期时间型字段,用于接受日期时间类型的数据 |
FileField | 文件上传字段,用于接受上传文件类型的数据 |
RadioField | 单选按钮字段 |
CheckboxField | 复选框字段 |
验证器:
DataRequired | 确保字段不为空 | message |
---|---|---|
EqualTo | 比较两个字段的值是否相等 | message, fieldname |
Length | 确保字段值的长度在给定范围内 | message, min, max |
确保字段值是合法的电子邮件地址 | message | |
URL | 确保字段值是合法的 URL 地址 | message |
NumberRange | 确保字段值在数字范围内 | message, min, max |
Regexp | 使用正则表达式验证字段值 | message, regex |
Optional | 使字段变为可选项 | 无 |
参数message表示自定义错误提示信息。如果参数未指定,则使用默认的错误提示信息。
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualToclass RegistrationForm(FlaskForm):"""注册表单类"""username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])email = StringField('Email', validators=[DataRequired(), Email()])password = PasswordField('Password', validators=[DataRequired()])confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])submit = SubmitField('Sign Up')
这个表单类定义了一个用户注册表单,包含用户名、电子邮件、密码和确认密码等字段。
其中,StringField
表示字符串类型的字段,PasswordField
表示密码类型的字段,SubmitField
表示提交按钮类型的字段。
验证器中,DataRequired
表示该字段必须填写,Length
表示该字段长度限制,Email
表示该字段必须是电子邮件格式,EqualTo
表示该字段必须与另一个字段相等。
最后,submit
表示提交按钮。
视图函数中,可以通过创建一个表单对象来渲染表单,并将其传递给模板进行渲染。
在模板中,可以使用 form.
来渲染表单字段。
下面是一个简单的视图函数的示例:
from flask import render_template
from app import app
from forms import LoginForm@app.route('/login')
def login():form = LoginForm()return render_template('login.html', form=form)
处理表单提交时的一般流程如下:
request
对象;request
对象中获取表单数据,对数据进行验证和处理;在Flask中,常用的数据库操作有两种方式:
下面我们主要介绍使用SQLAlchemy的方式。
SQLAlchemy是Python中最著名的ORM框架之一,它提供了高度封装的SQL操作方式,可以让我们使用Python语言来操作数据库,而不用编写复杂的SQL语句。
SQLAlchemy还提供了非常好的数据模型定义方式,可以大大减少我们编写数据库代码的工作量。
pip install SQLAlchemy
安装完成后,我们需要在Flask应用中配置数据库连接,以便于在应用中使用。Flask中的数据库连接配置通常保存在app.config对象中。
from flask import Flask
from flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://username:password@hostname/database_name'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
上面的代码中,我们定义了一个Flask应用,并使用SQLAlchemy连接到了一个MySQL数据库。
其中,'username’和’password’分别是数据库用户名和密码,'hostname’是数据库服务器地址,'database_name’是数据库名。
在Flask应用中,我们需要定义数据模型类,以便于ORM框架进行数据操作。
下面是一个简单的数据模型类的定义:
from datetime import datetime
from flask_sqlalchemy import SQLAlchemydb = SQLAlchemy()class User(db.Model):__tablename__ = 'users'id = db.Column(db.Integer, primary_key=True)name = db.Column(db.String(50), nullable=False)email = db.Column(db.String(120), unique=True, nullable=False)password = db.Column(db.String(60), nullable=False)created_at = db.Column(db.DateTime, default=datetime.utcnow)def __repr__(self):return ''.format(self.name)
上面的代码中,我们定义了一个User数据模型类,它继承自db.Model类,这个类是SQLAlchemy提供的基类,用来定义数据模型类。
在User类中,我们定义了表名、字段名和字段类型等信息,这些信息会被SQLAlchemy自动映射到数据库中。
在__repr__方法中,我们定义了打印对象时的输出信息。
定义好数据模型类之后,我们就可以使用ORM框架进行数据操作了。
ORM框架提供了各种各样的查询方法,例如查询所有数据、查询单个数据、过滤数据等。
下面是一些简单的查询方法的例子:
# 查询所有用户
users = User.query.all()# 查询第一个用户
user = User.query.first()# 根据id查询用户
user = User.query.get(1)# 过滤数据
users = User.query.filter_by(name='Alice').
上一篇:mac在命令行里获取root权限