一、Flask模型介绍
官方文档:https://dormousehole.readthedocs.io/en/latest/
Flask是MTV模型即:
View:视图名(就是路由,为业务逻辑层), 负责业务逻辑,并在使用的时候调用Model和Template
用于封装负责处理用户在前端的请求及返回响应的逻辑。视图可以看作是前端与数据库的中间人,使他们连贯起来,达到用户在前端把想要的数据从数据库中读出来。也会将用户要想保存的数据进行操作写入到数据库。
Model:模型(创建表,为数据存取层) ,负责业务对象与数据库的对象(ORM)
ORM 是 Object Relational Mapper 的简写,就是关系对象映射器的意思。
该层处理与数据相关的所有事务: 如何存取、如何验证有效,是一个抽象层,用来构建和操作你的web应用中的数据,模型是你的数据的唯一的、权威的信息源。它包含你所储存数据的必要字段和行为。通常,每个模型对应数据库中唯一的一张表。
Template:负责如何将页面展示给用户(表现层)
直白来讲就是前端HTML给用户友好方便的展示查看
注意:可以没有Model和Template,但是必须要有View模块
- 先安装Flask
pip install Flask
- Model中用到的第三方库:
pip install Flask- SQLAlchemy # 操作数据库 (版本不能过高 1.0~2.0.3可用)
pip install Flask-Migrate # 映射修改数据库 (版本不能过高(含2.7以下都可用)
pip install PyMysql # 用于连接mysql
- View中用到的第三方库:
pip install Flask-WTF
pip install Flask-Bootstrap
- Template由于下载Flask时自带Jinja2,所以无需下载
Jinja是一个快速、富有表现力、可扩展的模板引擎。模板中的特殊占位符允许编写类似于Python语法的代码,然后向模板传递数据以呈现最终文档。
- Flask的命令行工具
pip install Flask-Script
关于SQLAlchemy的额外补充:
SQLAlchemy 是 Python 中一个通过 ORM 操作数据库的框架。
SQLAlchemy对象关系映射器提供了一种方法,用于将用户定义的Python类与数据库表相关联,并将这些类(对象)的实例与其对应表中的行相关联。它包括一个透明地同步对象及其相关行之间状态的所有变化的系统,称为工作单元,以及根据用户定义的类及其定义的彼此之间的关系表达数据库查询的系统
官方解释: 它提供了一整套众所周知的企业级持久性模式,旨在实现高效,高性能的数据库访问,并采用简单的Pythonic域语言。
可以让我们使用类和对象的方式操作数据库,从而从繁琐的 sql 语句中解脱出来。
二、匹配路由
先创建一个Flask项目, 创建完成之后会出现如下目录结构
|-- static(存放css、js、img)
|-- templates(存放html)
|-- app.py
使用pycharm创建后,会出现app.py文件的以下内容
文件是一个Flask的基础Demo,路由是通过@app.route装饰器实现URL和视图函数的注册
# app.py
from flask import Flask
app = Flask(__name__)
# 路由都是通过@app.route装饰器实现URL和视图函数的注册
@app.route("/")
# 这个是视图函数,route里面跟的是路径,只有用户正确访问路径(匹配到),就是执行对应的函数
def main():
return "hello world"
if __name__ == '__main__':
app.run(port=xx, host="xxxx", DEBUG=True/False) # 启动服务,里面的参数不写就是默认值
# 浏览器访问:http://127.0.0.1:5000/ 显示hello world
1、查看app的配置内容及导入配置文件:
print(app.config)
# 查看app的配置项,比如{'ENV': 'production', 'DEBUG': False,…………}
app.config.from_object(setting) # 导入setting.py的配置文件
DEBUG=True,一般用于开发模式,只要代码有改动,就会实时加载代码,不用重启服务,前提是不能报错
2、add_url_rule 和 route的联系:
—>> 源码中使用了 add_url_rule 这个函数,使用 view_func 参数进行建立映射关系
@app.route("/home")
def test():
return "hello world" # 返回值不能是数字
等价于 --->> 根据route装饰器源码可知,下面的代码也可以实现
def test():
return "hello world"
app.add_url_rule('/home', view_func=test)
3、通过把 URL 的一部分标记为 <variable_name> 就可以在 URL 中添加变量。
–>例如:string:name
@app.route("/test02/<string:name>") --> 可以是int、uuid、float、path
def test02(name):
"""
如果路径中有变量,那么函数中一定要写参数,否则会报错
"""
return f"this is test02 {name}"
注意点:path 可以跟任何值
4、唯一的 URL / 重定向行为
1、当在浏览器输入:localhost/test02的时候,状态码返回308重定向,
2、然后再请求/test02/,所以加不加斜杠,都是执行第一个函数
@app.route("/test02/")
def test02():
return f"this is test02 加斜杠"
@app.route("/test02")
def test02():
return f"this is test02 不加斜杠"
5、测试:路径访问场景
1、路径没有"/“时,加上”/“会报错,浏览器自己不会去掉”/",
@app.route("/test06")
def test06():
return f"<h1> this is test06 路径是:/test06</h1> "
# 结果:用户输入"/test06/", 找不到路径会报错
2、路径有"/“,用户没有填加,会重定向给添加上”/"
@app.route("/test06/")
def test06():
return f"<h1> this is test06 路径是:/test06/</h1> "
# 结果:用户输入"/test06", 先重定向,添加上"/",然后再去找路径,所以能正常访问到
6、反向解析或者映射 --> url_for()
# 一般是根据路径得名称。
# url_for根据名称寻路径,所以是反向
示例:
app.route("/username/update", endpoint="us_update")
def update():
return "update username"
@app.route("/test")
def test():
url = url_for("us_update") # 进行映射或者路由反向解析,主要是对视图函数中 endpoint 的值进行查找
print("测试url_for的内容:", url) # 打印内容:/username/update
return url
endpoint: 主要用于寻找,可能某些路径过长不好记,endpoint的值类似于小名,找到小名,就可以找到该函数
7、渲染模板中html的内容 --> render_template(“xx.html”, context)
# 前提:在templates文件夹中,先创建一个xx.html的文件,内容随意
app.route("/home")
def home():
# 会自动从templates文件夹中找到名称为xx.html的文件进行渲染
return render_template("xx.html", **context)
# **context:可以跟参数,传入到 html里面
# 引用传入文件里面的变量 --> html引用规则:{{ 变量名 }}
8、 重定向 --> redirect()
@app.route("/home",endpoint='haha')
@def user_home():
return "hello"
@app.route("/update")
def update():
return redirect("/home") # 先有302的重定向,然后再去请求"/home",所以是两个请求
# return redirect("haha") 等价于上面
总结:视图函数可以返回的结果:
–> 1、str --> 自动转化成Response对象
–> 2、dict --> json
–> 3、tuple
–> 4、Response 对象
–> 5、make_response
–> 6、render_template(“xxx.html”) # 渲染内容 模板
–> 7、redirect() 重定向 默认是302