文件结构
Project/ ├── config/ # Flask应用初始化文件 │ └── static/ # 存放静态文件 │ └── images/ # 静态图片 ├── routes/ # 存放路由定义的文件夹 │ ├── login.py # 例如:登录路由 │ └── ... # 其他路由文件 ├── services/ # 存放对应路由实现代码的文件夹 │ ├── login.py # 例如:登录功能的实现 │ └── ... # 其他实现文件 └──app.py # 启动Flask应用的脚本
app.py 示例:
from config.db_config import app from flask import Flask, send_from_directory # 添加路径 /background from routes.background import background # 导入包 app.register_blueprint(background, url_prefix="/background") #添加蓝图 # 访问根路径会执行 @app.route('/') def ping(): return 'ok' # 访问静态文件 @app.route('/images/<filename>') def get_image(filename): return send_from_directory('static', filename) if __name__ == '__main__': app = Flask(__name__) # 创建app app.run(host='127.0.0.1', port=5000, debug=True) # 广播
当前端访问http://127.0.0.1/
,会执行ping()
函数,返回ok
当前端访问http://127.0.0.1/images/图片.png
,会执行get_image()
函数,得到一张图片文件
总结:
# app.py # 添加路径 from routes.分支文件名 import 分支变量名 app.register_blueprint(分支变量名 , url_prefix="/分支名 ") @app.route('/path') def fun_name(): 函数的具体处理 if __name__ == '__main__': app = Flask(__name__) # 创建app app.run(host='本机ip,一般为127.0.0.1,广播0.0.0.0, port=端口号, debug=True)
在app.py
的示例中,我定义了路径'/background'
,下面我们就可以在routes文件夹中添加background.py
,实现前端请求该路径后,后端返回 JSON格式的代码。
import json from flask import Blueprint, request from services.background import Background_operation # 导入services中的操作 background = Blueprint('background', __name__) # 注册路由 s = Background_operation() # 操作类 @background.route('/login', methods=['POST']) # methods是访问方式,有Get和Post两中 def login(): data = json.loads(request.data) # 获取前端发来的信息,JSON格式 user_id = data['user_id'] password = data['password'] result = s.login(user_id, password) # 调用操作类中的函数 return result # 返回的是JSON格式
当前端访问http://127.0.0.1/background/login
时 ,会执行login()
函数,返回 JSON文件。具体的细节操作操作在services文件夹中的文件实现。
总结:
# 定义蓝图 分支 = Blueprint('分支 ', __name__) # 注册路由 操作类实例 = 分支 _operation() # 在services中实现 # 写一个url的请求,此处url是 http://127.0.0.1:5000/route/function_1 @分支.route('/funtion_1', methods=['GET']) #分配路由,methods有 GET请求 / POST请求 def funtion_1(): 这里写访问接口后的操作(函数里可以实现的内容) - 获取前端传递参数 - 业务处理 - 与数据库交互 - 返回JSON数据 result = 操作类实例.实现funtion具体操作的funtion() return result @分支.route('/funtion_2', methods=['POST']) #分配路由 def funtion_2(): ···
在services文件夹里写function的具体实现。(这里就可以调用模型)
这里是实现上文登录操作的登录类。
class Background_operation: def __init__(self): super().__init__() def login(self, user_id, password): if user_id != 'admin' and password != '123456': return jsonify({'code': -1, 'message': '账号不存在或密码错误', 'data': {}}) return jsonify({'code': 0, 'message': '登录成功', 'data': {"key":"value"})
当账号是admin
并且密码为123456
时,返回登录成功的信息,否则返回登录失败的信息。
在Background_operation
类中,还可以继续添加需要的函数,以实现更多功能。
添加数据库
连接数据库
在config文件夹下创建 db_config.py
文件,并删除app.py中app = Flask(__name__) # 创建app
这一行。
from flask import Flask from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) # 创建app app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://用户名:密码@127.0.0.1:3306/数据库名' db_init = SQLAlchemy(app) # 数据库初始化对象
映射数据表(Model ORM)
在项目文件夹下创建 models
文件夹,在文件夹中添加模型文件。
例如user.py
:
from config.db_config import db_init as db class User(表名)(db.Model): __tablename__ = 'user(表名)' 属性 = db.Column(属性在数据库中的定义) # 也就是数据表的一列的定义 # 例如: id = db.Column(db.String(255), primary_key=True, nullable=False) #id属性,char类型、主键、不为空 name = db.Column(db.String(255), nullable=False) #name属性,char类型、不为空 password= db.Column(db.String(255), nullable=False) #password属性,char类型、不为空 def to_dict(self): #转为Json格式 return { 'id': self.id, 'name': self.name, 'password': self.password }
注意:password一般不能明文存储。本文为了方便演示,没有加密解密操作。
在services文件中添加对数据库表的操作
还是登录这个例子,上文services/background.py
中,login()
函数就能改成以下形式
class Background_operation: def __init__(self): super().__init__() def login(self, user_id, password): user = User.query.filter_by(id=user_id).first() # 查询表中,有没有id=user_id的记录。第一条记录赋值给user if user is None: return jsonify({'code': -1, 'message': '账号不存在', 'data': {}}) # 没有id=user_id的记录 user_dict = user.to_dict() # 转为JSON格式 if user_dict['password'] != password: return jsonify({'code': -2, 'message': '密码错误', 'data': {}}) # 密码不一致 re_dict = user.to_dict_without_password() # 不要明文返回密码 return jsonify({'code': 0, 'message': '登录成功', 'data': re_dict})
flask连接MySQL数据,新手优先推荐使用pymysql降低出错的几率
下载驱动包pymysql,在终端使用命令安装,安装命令如下
pip install pymysql
安装flask_sqlalchemy包,使得flask在使用sqlalchemy时更加方便
pip install flask-sqlalchemy
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) # 创建app
HOSTNAME = "localhost" # MySQL所在主机名,默认127.0.0.1
PORT = 3306 # MySQL监听的端口号,默认3306
USERNAME = "root" # 连接MySQL的用户名,自己设置
PASSWORD = "root" # 连接MySQL的密码,自己设置
DATABASE = "database_learn" # MySQL上创建的数据库名称
# 通过修改以下代码来操作不同的SQL比写原生SQL简单很多 --》通过ORM可以实现从底层更改使用的SQL
app.config['SQLALCHEMY_DATABASE_URI'] = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
db = SQLAlchemy(app)
** 要自己创建数据库和表,不是自动生成的表
报错: RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods
pip install cryptography
数据迁移 (这个暂时没用上)
在 Flask 中执行数据库迁移,通常会使用 Flask-Migrate 扩展,它是基于 Alembic 的一个简单包装器,用于处理数据库迁移。以下是如何使用 Flask-Migrate 执行数据迁移的基本步骤:
安装Flask-Migrate
pip install Flask-Migrate