1、flask微服务含义
“微”并不代表整个应用只能塞在一个 Python 文件内, 当然塞在单一文件内也没有问题。 “微”也不代表 Flask 功能不强。 微框架中的“微”字表示 Flask 的目标是保持核心简单而又可扩展。 Flask 不会替你做出许多决定,比如选用何种数据库。 类似的决定,如使用何种模板引擎,是非常容易改变的。 Flask 可以变成你任何想要的东西,一切恰到好处,由你做主。
缺省情况下, Flask 不包含数据库抽象层、表单验证或者其他已有的库可以处理的东西。 然而, Flask 通过扩展为你的应用添加这些功能,就如同这些功能是 Flask 生的一样。 大量的扩展用以支持数据库整合、表单验证、上传处理和各种开放验证等等。Flask 可能是 “微小”的,但它已经为满足您的各种生产需要做出了充足的准备。
【摘自flask中文文档】
2、flask框架安装
Anaconda Prompt:
1、创建一个虚拟环境
conda create -n flask python=3.7
2、激活虚拟环境
activate flask
3、虚拟环境下安装flask框架
pip install flask
pip install flask-sqlalchemy
3、flask最小应用
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello, World!'
- 首先我们导入了Flask类。 该类的实例将会成为我们的 WSGI 应用。
- 接着我们创建一个该类的实例。第一个参数是应用模块或者包的名称。如果你使用 一个单一模块(就像本例),那么应当使用
__name__
,因为名称会根据这个 模块是按应用方式使用还是作为一个模块导入而发生变化(可能是 ‘main’ , 也可能是实际导入的名称,如package01.A)。这个参数是必需的,这样 Flask 才能知道在哪里可以 找到模板和静态文件等东西。 - 然后我们使用route()装饰器来告诉 Flask 触发函数的 URL 。
- 函数名称被用于生成相关联的 URL 。函数最后返回需要在用户浏览器中显示的信息。
4、蓝图路由规划
视图
视图是一个应用对请求进行响应的函数。【如上hello_world()】
Flask 把请求 URL 匹配到 对应的处理视图。视图返回数据,Flask 把数据变成出去的响应。
当然,Flask 也可以反过来,根据视图的名称和参数找到 URL 。
蓝图
Blueprint是一种组织相关视图及其他代码的方式,与把视图及其他代码直接注册到应用的方式不同,蓝图方式是把它们先注册到蓝图,然后在工厂函数中把蓝图注册到应用。
(理解为将某个页面相关的URL与它们对应的视图函数专门用一个.py管理,然后再在flask app小程序上注册,则可以设定页面前缀等)
1、这里创建了一个名称为 route_imooc
的Blueprint 。和app
一样, 蓝图需要知道是在哪里定义的,因此把 __name__
作为函数的第二个参数。 第三个参数url_prefix
会添加到所有与该蓝图关联的 URL 前面,可以在这定义,或是在小程序注册蓝图时定义。
本文选择注册时候定义。
from flask import Blueprint
route_imooc = Blueprint("imooc_page", __name__)
@route_imooc.route("/")
def index():
return "imooc index page"
@route_imooc.route("/hello")
def hello():
return "imooc hello world"
2、小程序注册蓝图
from imooc import route_imooc # 导入蓝图
app = Flask(__name__)
app.register_blueprint(route_imooc, url_prefix="/imooc") # 注册蓝图
PS:定义路由URL时,尽量不要再在最后+“/”,是为了保证路径唯一性。
5、链接管理
url_for()函数用于构建指定函数的 URL
@app.route("/")
def index():
url = url_for("hello")
return url
@app.route("/hello")
def hello():
pass
为什么不在把 URL 写死在模板中,而要使用反转函数url_for()
动态构建?【摘自flask中文文档】
- 反转通常比硬编码 URL 的描述性更好。
- 你可以只在一个地方改变 URL ,而不用到处乱找。
- URL 创建会为你处理特殊字符的转义和 Unicode 数据,比较直观。
- 生产的路径总是绝对路径,可以避免相对路径产生副作用。
- 如果你的应用是放在 URL 根路径之外的地方(如在
/myapplication
中,不在/
中),url_for()
会为你妥善处理。
6、日志系统
app自身封装logging.logger
app.logger.info(msg)
app.logger.error(msg)
app.logger.debug(msg)
7、错误处理
针对小程序级别的错误处理
@app.errorhandler(404)
def page_not_found(error):
app.logger.error(error)
return 'This page does not exist', 404
8、数据库ORM
常见情况下对于只有一个 Flask 应用,所有您需要做的事情就是创建 Flask 应用,选择加载配置,接着创建 sqlalchemy
对象时候把 Flask 应用传递给它作为参数。
一旦创建,这个对象就包含 sqlalchemy
和sqlalchemy.orm
中的所有函数和助手。此外它还提供一个名为 Model 的类,用于作为声明模型时的基类。
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:[email protected]:3306/flask'
db = SQLAlchemy(app)
MySQL配置表达形式:mysql://username:password@hostname/database
我们可以通过不同的方法操作数据库
现在,假设本地有个flask数据库,其中有个user表,
1、sql语句执行
@app.route("/hello")
def hello():
from sqlalchemy import text
sql = text("SELECT * FROM user ")
result = db.engine.execute(sql)
msg = ''
for row in result:
msg += str(row)
return msg
![image-20220816132120953](/i/l/?n=22&i=blog/2103542/202210/2103542-20221001110320237-414261516.png)
2、类对象操作
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(), unique=True)
password = db.Column(db.String(), unique=True)
def __init__(self, username, password):
self.username = username
self.password = password
def __str__(self):
return 'User %s %s' % (self.username, self.password)
@app.route("/hello2")
def hello2():
users = User.query.all()
msg = ''
for each in users:
msg += str(each)
return msg
![image-20220816135641457](/i/l/?n=22&i=blog/2103542/202210/2103542-20221001110320539-1566484556.png)
详见flask-sqlalchemy官方文档:
http://www.pythondoc.com/flask-sqlalchemy/quickstart.html