diff --git a/doc/flask/README.md b/doc/flask/README.md index cda200dbc36b6cf53cbf5385245bba09aafbac06..547cb62234f6605b951fc191b096d062a41839a7 100644 --- a/doc/flask/README.md +++ b/doc/flask/README.md @@ -1,3 +1,12 @@ ## 更新日志 :id=log -> 当前版本:`Flask 1.00.release`,更新于:`2021-06-03`,查看 [在线演示](http://flask.pearadmin.com/)。 +#### 2023-02-10 ( 1.00.release ) + +> 此次更新日志是几次PR提交的集合。 + +- [修复] **master分支:** url_for函数拼接静态文件路径可能发生的308错误。FROM [Teishorin](https://gitee.com/teishorin)'s PR。 +- [修复] **master分支:** 对于鉴权逻辑,管理员可以获得访问全部权限白名单。FROM [不胜舟](https://gitee.com/resonate)'s commit。 +- [新增] **master分支:** Flask-APScheduler 功能设定。FROM [CHunYenc](https://gitee.com/CHunYenc)'s PR。 +- [新增] **master分支:** 添加邮件管理模块。FROM [mengfu188](https://gitee.com/mengfu188)'s PR。 +- [修复] **master分支:** 优化验证与过滤。FROM [不胜舟](https://gitee.com/resonate)'s commit。 +- [新增] **master分支:** 插件功能。FROM [我叫以赏](https://gitee.com/wojiaoyishang)'s PR。 \ No newline at end of file diff --git a/doc/flask/_sidebar.md b/doc/flask/_sidebar.md index 32637b6b54bdb7eab2b49e3fff615add051df08c..c9c7e18ef316b52f151ac8793c8b525a308077be 100644 --- a/doc/flask/_sidebar.md +++ b/doc/flask/_sidebar.md @@ -1,8 +1,11 @@ * [开始使用](start/?id=install) * [下载安装](install/) -* [权限管理](admin/auth) * [项目结构](admin/list) -* [公共函数](admin/base) +* [公共函数](javascript:;) + - [权限管理](function/auth) + - [model 序列化](function/base) + - [其他函数](function/utils) +* [插件开发](admin/plugin) * [常见问题](help/)
diff --git a/doc/flask/admin/list.md b/doc/flask/admin/list.md index f55596165c414be15e7c92302a29e8160197344d..9572a0c04e9dee9e619cb14f4e16eed07fd27a8a 100644 --- a/doc/flask/admin/list.md +++ b/doc/flask/admin/list.md @@ -1,9 +1,46 @@ ## 应用结构 :id=config ```应用结构 - +Pear Admin Flask(master分支) +├─applications # 应用 +│ ├─configs # 配置文件 +│ │ ├─ common.py # 普通配置 +│ │ └─ config.py # 配置文件对象 +│ ├─dev # 插件开发文件 +│ ├─extensions # 注册插件 +│ ├─models # 数据模型 +│ ├─static # 静态资源文件 +│ ├─templates # 静态模板文件 +│ └─views # 视图部分 +│ ├─admin # 后台管理视图模块 +│ └─index # 前台视图模块 +├─docs # 文档说明(占坑) +├─migrations # 迁移文件记录 +├─requirement # 依赖文件 +├─test # 测试文件夹(占坑) +└─.env # 项目的配置文件 ``` ## 资源结构 :id=static ```资源结构 - +Pear Admin Flask (master分支) +├─static # 项目设定的 Flask 资源文件夹 +│ ├─admin # pear admin flask 的后端资源文件(与 pear admin layui 同步) +│ ├─index # pear admin flask 的前端资源文件 +│ └─upload # 用户上传保存目录 +└─templates # 项目设定的 Flask 模板文件夹 + ├─admin # pear admin flask 的后端管理页面模板 + │ ├─admin_log # 日志页面 + │ ├─common # 基本模板页面(头部模板与页脚模板) + │ ├─console # 系统监控页面模板 + │ ├─dept # 部门管理页面模板 + │ ├─dict # 数据自动页面模板 + │ ├─mail # 邮件管理页面模板 + │ ├─photo # 图片上传页面模板 + │ ├─plugin # 插件管理页面模板 + │ ├─power # 权限(菜单)管理页面模板 + │ ├─role # 角色管理页面模板 + │ ├─task # 任务设置页面模板 + │ └─user # 用户管理页面模板 + ├─errors # 错误页面模板 + └─index # 主页模板 ``` \ No newline at end of file diff --git a/doc/flask/admin/plugin.md b/doc/flask/admin/plugin.md new file mode 100644 index 0000000000000000000000000000000000000000..de888ff287ccc021222652257b1e9f1c5c8ea371 --- /dev/null +++ b/doc/flask/admin/plugin.md @@ -0,0 +1,69 @@ +### 说明 + +插件功能旨在最大限度不修改原框架的前提下添加新功能,我们提供了三个示例插件。 + +> 插件功能需要最新版的 master 分支。 + +### 插件配置 + +将插件文件夹放置在 ```plugins``` 文件夹中,并且在 .flaskenv 中配置。再配置项中填入插件的文件夹名,已 json 格式写入其中。 + +```.flaskenv +# 插件配置 +PLUGIN_ENABLE_FOLDERS = ["helloworld"] +``` + +### 插件目录 + +``` +Plugin +│ __init__.json +└─ __init__.py +``` + +这是一个非常简单的插件。 + +### 插件信息 + +插件信息保存在 ```__init__.py``` 中,以测试插件“helloword”为例。插件的数据应该不少于下面三项: + +```json +{ + "plugin_name": "Hello World", + "plugin_version": "1.0.0.1", + "plugin_description": "一个测试的插件。" +} +``` + +### 插件格式 + +插件的入口点为 ```__init__.py``` 文件,在插件被启用后,程序启动时此 Python 文件中的 ```event_init``` 函数。代码如下: + +```python +from flask import Flask + +def event_init(app: Flask): + """初始化完成时会调用这里""" + print("加载完毕后,我会输出一句话。") +``` + +调用时需要一个参数来接收``app``。 + +插件还有另外两个事件:```event_enable```、```event_disable```。分别在插件被启用时与被禁用时执行的函数。 + +```python +import os + +# 获取插件所在的目录(结尾没有分割符号) +dir_path = os.path.dirname(__file__).replace("\\", "/") +folder_name = dir_path[dir_path.rfind("/") + 1:] # 插件文件夹名称 + +def event_enable(): + """当此插件被启用时会调用此处""" + print(f"启用插件,dir_path: {dir_path} ; folder_name: {folder_name}") + +def event_disable(): + """当此插件被禁用时会调用此处""" + print(f"禁用插件,dir_path: {dir_path} ; folder_name: {folder_name}") + +``` \ No newline at end of file diff --git a/doc/flask/admin/auth.md b/doc/flask/function/auth.md similarity index 39% rename from doc/flask/admin/auth.md rename to doc/flask/function/auth.md index 0304b64dcc0b2fee2f8605c01e3f864ad6d823b0..1647947338c60c8b87648d576eaf4fca4bd6769f 100644 --- a/doc/flask/admin/auth.md +++ b/doc/flask/function/auth.md @@ -1,20 +1,45 @@ -### 权限管理 :id=authorize +### 说明 :id=authorize -使用装饰器 @authorize时需要注意,该装饰器需要写在 @app.route 之后 +Pear Admin Flask 项目中集成很多实用的功能,为了便于二次开发,同样也提供了许多便于开发的自定义函数。 + +Pear Admin Flask 项目支持多用户,不同用户有不同的权限,此处将介绍 Pear Admin Flask 中的权限管理函数的用法。 + +> 此处针对 master 分支,其他分支等待完善。 + +### 函数原型 + +函数调用位于项目代码 ```applications/common/utils/rights.py``` 中,函数原型如下: ```python -@authorize(power: str, log: bool) +def authorize(power: str, log: bool = False): + """ + 用户权限判断,用于判断目前会话用户是否拥有访问权限 + + :param power: 权限标识 + :type power: str + :param log: 是否记录日志, defaults to False + :type log: bool, optional + """ + ... ``` -第一个参数为权限 code +### 基本用法 -第二个参数为是否生成日志 ++ 后端用法 ```python -# 例如 +from applications.common.utils.rights import authorize + +@app.route("/test") @authorize("admin:power:remove", log=True) +def test_index(): + return 'You are allowed.' ``` +> 使用装饰器 @authorize时需要注意,该装饰器需要写在 @app.route之后 + ++ 前端用法 + 在前端中,例如增加,删除按钮,对于没有编辑权限的用户不显示的话,可以使用 `{% **if** authorize("admin:user:edit") %}` diff --git a/doc/flask/admin/base.md b/doc/flask/function/base.md similarity index 55% rename from doc/flask/admin/base.md rename to doc/flask/function/base.md index bee921c4b74749be47dfdc05bd53ba123cba9dbd..1b6ad77daee09cbceeedf913513b2ecbfcb59697 100644 --- a/doc/flask/admin/base.md +++ b/doc/flask/function/base.md @@ -1,13 +1,12 @@ -## model序列化 :id=Schema +### 说明 :id=Schema -- sqlalchemy查询的model对象转dict +项目中时常会涉及到数据库的读写,在读入数据时可以采用SQLalchemy,将模型查询的数据对象转化为字典。 - -``` - model_to_dicts(Schema, model) -``` +> 此处针对 master 分支,其他分支等待完善。 + +### Schema 序列化 -Schema 是 序列化类,我把他放在了models文件里,觉得没有必要见一个文件夹叫Schema,也方便看着模型写序列化类 +> Schema 是序列化类,我们把他放在了models文件里,因为觉得没有必要新建一个文件夹叫 Schema ,也方便看着模型写序列化类。 ```python # 例如 @@ -23,22 +22,44 @@ class DeptSchema(ma.Schema): # 序列化类 sort = fields.Str() ``` ->这一部分有问题的话请看marshmallow文档 +> 这一部分有问题的话请看 marshmallow 文档 -model写的是查询后的对象 +### 模型到字典 -```python -dept = Dept.query.order_by(Dept.sort).all() +#### 函数原型 + +函数调用位于项目代码 ```applications/common/curd.py``` 中,函数原型如下: + +``` +def model_to_dicts(schema: ma.Schema, data): + """ + 将模型查询的数据对象转化为字典 + + :param schema: schema类 + :param model: sqlalchemy查询结果 + :return: 返回单个查询结果 + """ + ... ``` -进行序列化 +#### 基本用法 + ++ model写的是查询后的对象 ```python -res = model_to_dicts(Schema=DeptSchema, model=dept) +from applications.common import curd +from applications.models import Dept +from applications.schemas import DeptOutSchema + +def test(): # 某函数内 + dept = Dept.query.order_by(Dept.sort).all() + res = curd.model_to_dicts(Schema=DeptOutSchema, model=dept) ``` ## 查询多字段构造器 +> 此内容不属于 matser 分支 + ```python from applications.common.helper import ModelFilter mf = ModelFilter() @@ -65,7 +86,7 @@ mf.less(field_name, value): mf.vague(field_name, value: str): # 左模糊 (% + xxx) - mf.left_vague(field_name, value: str): +mf.left_vague(field_name, value: str): # 右模糊查询字段(xxx+ %) mf.right_vague(field_name, value: str): @@ -80,12 +101,10 @@ mf.between(field_name, value1, value2) # 查询 你的Model.query.filter(mf.get_filter(model=User)).all() - - - # 例如 +# 例如 - # 获取请求参数 +# 获取请求参数 real_name = xss_escape(request.args.get('realName', type=str)) username = xss_escape(request.args.get('username', type=str)) dept_id = request.args.get('deptId', type=int) @@ -101,53 +120,4 @@ mf = ModelFilter() # 使用分页获取data需要.items user = User.query.filter(mf.get_filter(model=User)).layui_paginate() -``` - -## xss过滤 - -```python -from applications/common/utils/validate import xss_escape -real_name = xss_escape(request.args.get('realName', type=str)) -``` - - - -## 邮件发送 - -```python -#在.flaskenv中配置邮箱 - -from applications/common/utils/mail import send_main -send_mail(subject='title', recipients=['123@qq.com'], content='body') -``` - - - -## 返回格式 - -``` -from applications/common/utils/http import success_api,fail_api,table_api - -# 这是源代码 -def success_api(msg: str = "成功"): - """ 成功响应 默认值”成功“ """ - return jsonify(success=True, msg=msg) - - -def fail_api(msg: str = "失败"): - """ 失败响应 默认值“失败” """ - return jsonify(success=False, msg=msg) - - -def table_api(msg: str = "", count=0, data=None, limit=10): - """ 动态表格渲染响应 """ - res = { - 'msg': msg, - 'code': 0, - 'data': data, - 'count': count, - 'limit': limit - - } - return jsonify(res) ``` \ No newline at end of file diff --git a/doc/flask/function/utils.md b/doc/flask/function/utils.md new file mode 100644 index 0000000000000000000000000000000000000000..ae615530d72272bef482650c84b8038d3f04fdb7 --- /dev/null +++ b/doc/flask/function/utils.md @@ -0,0 +1,157 @@ +### 说明 :id=utils + +Pear Admin Flask 项目中还提供了若干个便于后端操作的函数。以及,在于前端通信时也有一个规定的返回信息格式,此章将介绍这些函数。 + +这些函数的原型均位于 ```applications/common/utils``` 中,各位开发者可以打开源代码进行参考。 + +> 此处针对 master 分支,其他分支等待完善。 + +### xss过滤 + +#### 函数原型 + +函数调用位于项目代码 ```applications/common/utils/validate.py``` 中,函数原型如下: + +``` +def str_escape(s: str) -> str: + """ + xss过滤,内部采用flask自带的过滤函数。 + 与原过滤函数不同的是此过滤函数将在 s 为 None 时返回 None。 + + :param s: 要过滤的字符串 + :type s: str + :return: s 为 None 时返回 None,否则过滤字符串后返回。 + :rtype: str + """ + ... +``` + +#### 使用方法 + +```python +from applications.common.utils.validate import str_escape +real_name = xss_escape(request.args.get('realName', type=str)) +``` + + +### 邮件发送 + ++ 原邮件发送函数 + +#### 函数原型 + +函数调用位于项目代码 ```applications/common/utils/mail.py``` 中,函数原型如下: + +``` +def send_mail(subject, recipients, content): + """原发送邮件函数,不会记录邮件发送记录 + + 失败报错,请注意使用 try 拦截。 + + :param subject: 主题 + :param recipients: 接收者 多个用英文分号隔开 + :param content: 邮件 html + """ + ... +``` + +#### 实例代码 + +```python +#在.flaskenv中配置邮箱 +from applications.common.utils import mail + +mail.send_mail("subject", "test@test.com", "

Hello

") +``` + ++ 基于二次开发的邮件发送函数 + +#### 函数原型 + +函数调用位于项目代码 ```applications/common/utils/mail.py``` 中,函数原型如下: + +``` +def add(receiver, subject, content, user_id): + """ + 发送一封邮件,若发送成功立刻提交数据库。 + + :param receiver: 接收者 多个用英文逗号隔开 + :param subject: 邮件主题 + :param content: 邮件 html + :param user_id: 发送用户ID(谁发送的?) 可以用 from flask_login import current_user ; current_user.id 来表示当前登录用户 + :return: 成功与否 + """ + ... +``` + +#### 示例代码 + +```python +#在.flaskenv中配置邮箱 +from applications.common.utils import mail + +mail.add("test@test.com", "subject", "

Hello

", current_user) +``` + + + +### 返回格式 + +> 后端响应时我们推荐使用规定的API响应格式。 + +#### 函数原型 + +函数调用位于项目代码 ```applications/common/utils/http.py``` 中,函数原型如下: + +``` +def success_api(msg: str = "成功"): + """ 成功响应 默认值“成功” """ + return jsonify(success=True, msg=msg) + + +def fail_api(msg: str = "失败"): + """ 失败响应 默认值“失败” """ + return jsonify(success=False, msg=msg) + + +def table_api(msg: str = "", count=0, data=None, limit=10): + """ 动态表格渲染响应 """ + res = { + 'msg': msg, + 'code': 0, + 'data': data, + 'count': count, + 'limit': limit + + } + return jsonify(res) +``` + +#### 示例代码 + +```python +from applications.common.utils.http import success_api, fail_api, table_api + +@admin_log.get('/operateLog') +@authorize("admin:log:main") +def operate_log(): + # orm查询 + # 使用分页获取data需要.items + log = AdminLog.query.filter( + AdminLog.url != '/passport/login').order_by( + desc(AdminLog.create_time)).layui_paginate() + count = log.total + return table_api(data=model_to_dicts(schema=LogOutSchema, data=log.items), count=count) +``` + +```python +from applications.common.utils.http import success_api, fail_api, table_api + +@admin_power.post('/save') +@authorize("admin:power:add", log=True) +def save(): + ... # 若干操作 + if success: + return success_api(msg="成功") + return fail_api(msg="成功") +``` diff --git a/doc/flask/help/README.md b/doc/flask/help/README.md index fcef5055d2733e45f14f2f500dd057036e86b114..9891b9aa8f5e8d1214a5bd2a207b54753ee5fb2b 100644 --- a/doc/flask/help/README.md +++ b/doc/flask/help/README.md @@ -1 +1,6 @@ -暂无问题 \ No newline at end of file +> 若有问题请在项目的开源地址发布 issue 或者是 pr ,我们会及时为您解决问题。 + +#### 相关链接 ++ [Pear Admin 项目主页](https://gitee.com/pear-admin) ++ [Pear Admin Flask 项目仓库](https://gitee.com/pear-admin/pear-admin-flask) ++ [Pear Admin Layui 项目仓库](https://gitee.com/pear-admin/Pear-Admin-Layui) \ No newline at end of file diff --git a/doc/flask/index.html b/doc/flask/index.html index 155e060896dfaf5791111da318bfd37592f07b8e..54dd9fc809fe37cb26391cc4a874d78ad62c9181 100644 --- a/doc/flask/index.html +++ b/doc/flask/index.html @@ -17,7 +17,7 @@ -
加载中..
+
加载中...
diff --git a/doc/flask/install/README.md b/doc/flask/install/README.md index 64342d5f088f795da45ffb469c15bb31eaadefbd..7d51a339e6f343ff1b28bb124f42064056a04016 100644 --- a/doc/flask/install/README.md +++ b/doc/flask/install/README.md @@ -3,39 +3,102 @@ - Mysql >= 5.7.0 ### 安装配置 + +#### 克隆远程仓库 + +您可以使用 git 来克隆远程仓库: + ```shell +# 进入项目主目录 +cd Pear Admin Flask + +# 使用 git 克隆远程仓库 git clone https://gitee.com/pear-admin/pear-admin-flask.git -# 进 入 项 目 主 目 录 +# 切换分支 +git checkout master # master, main or mini +``` + +或者直接前往 Pear Admin Flask 项目的[Gitee 主页](https://gitee.com/pear-admin/pear-admin-flask)下载项目仓库。 + +#### 搭建开发环境 + +我们推荐使用 Python 的虚拟环境来开发该项目,这样便于项目的迁移与二次开发。当然,您也可以选择使用原 Python 环境。 -# 创 建 虚 拟 环 境 在 当 前 目 录 的 venv 文 件 夹 +如果你想创建 Python 虚拟环境,你可以使用下面的命令行: + +```shell +# 在当前目录的venv文件夹创建虚拟环境 python -m venv venv -# 激 活 虚 拟环 境 +# 激活虚拟环境 venv\Scripts\activate +``` + +**如果在创建虚拟环境时报错 “ModuleNotFoundError” ,这说明您的 Python 版本小于 3.3 。** -# 安 装 +#### 安装项目依赖 + +```shell +# 使用 pip 安装必要模块(对于 master 分支) +pip install -r requirement\requirement.txt + +# 使用 pip 安装必要模块(对于 mini 分支) pip install -r requirement.txt +``` -# 配 置 数 据 库 -applications\config\database.py +或者您可以尝试: -# 初始化数据库 -python dev/initDb.py +```shell +# 使用 pip 安装必要模块(对于 master 分支) +python -m pip install -r requirement\requirement.txt +# 使用 pip 安装必要模块(对于 mini 分支) +python -m pip install -r requirement.txt ``` +#### 配置数据库 + ++ master 分支: + +将项目文件中的 ```pear.sql``` 文件导入 Mysql 中。 + ++ mini 分支: +默认的使用 `sqlite3` 作为测试环境的数据库进行演示,不需要按照mysql即可查看演示。如果需要二次开发,建议改成 `mysql` 。 + +如果需要在开发环境使用 mysql 作为数据库,请查看 `applications/configs/config.py` 文件里面的相关配置文件, 注释掉 sqlite 的配置即可 + +如果需要修改数据的配置信息,请在 `.flaskenv` 里面调整即可 + +```bash +flask db init +flask db migrate -m '数据初始化' +flask db upgrade + +flask init-db +``` + ++ main 分支 + +```bash +-- 删除旧数据库 +drop database if exists pear_admin_flask; +-- 创建新数据库 +create database pear_admin_flask character set `utf8mb4`; +``` ### 设置 ++ master 分支 + ```.flaskenv .flaskenv文件 # flask配置 -FLASK_APP=app.py -FLASK_ENV=development -FLASK_DEBUG=1 -FLASK_RUN_HOST = 127.0.0.1 #如果远程开发或者内网访问,改成 0.0.0.0 +FLASK_APP = app.py +FLASK_ENV = development +FLASK_DEBUG = 1 +FLASK_RUN_HOST = 127.0.0.1 # 如果远程开发或者内网访问,改成 0.0.0.0 FLASK_RUN_PORT = 5000 # pear admin flask配置 @@ -57,13 +120,11 @@ REDIS_PORT=6379 SECRET_KEY='pear-admin-flask' #很重要,部署一定要改 # 邮箱配置 -MAIL_SERVER='smtp.qq.com' -MAIL_USERNAME='123@qq.com' -MAIL_PASSWORD='XXXXX' # 生成的授权码 +MAIL_SERVER = 'smtp.qq.com' +MAIL_USERNAME = '123@qq.com' +MAIL_PASSWORD = 'XXXXX' # 生成的授权码 ``` - - -- 如果局域网访问,将FLASK_RUN_HOST设置为 0.0.0.0 +- 如果想允许全部网络计算机访问,将FLASK_RUN_HOST设置为 0.0.0.0 。但是我们并不推荐在发布期间这么做,这无疑会增加被攻击的风险。 \ No newline at end of file diff --git a/doc/flask/start/README.md b/doc/flask/start/README.md index 29f4ad10c9c3fd856eb265c72ad21464d3e1fea7..75df6b42980251d519c1b38fd444d0e643bdf91a 100644 --- a/doc/flask/start/README.md +++ b/doc/flask/start/README.md @@ -1,15 +1,35 @@ ## 项目介绍 :id=start -Pear Admin Flask 基于 Flask 的后台管理系统,拥抱应用广泛的python语言,通过使用本系统,即可快速构建你的功能业务 +欢迎阅读 Pear Admin Flask 的开发文档!Pear Admin Flask 是一个基于 Flask 的后台管理系统,拥抱应用广泛的 Python 语言,通过使用本系统,即可快速构建你的功能业务。 -项目旨在为python开发者提供一个后台管理系统的模板,成为您构建信息管理系统,物联网后台....等等应用时灵活,简单的工具 +项目旨在为 Python 开发者提供一个后台管理系统的模板,成为您构建信息管理系统、物联网后台等应用时灵活、简单的工具。 -各位Python爱好者多多指教 +同时,Pear Admin Flask 项目也是一个对于 Python 初学者友好的项目。此项目处于开发初期,欢迎各位 Python 爱好者加入到 Pear Admin Flask 项目建设中来。如果您在使用此项目的过程中,发现项目代码存在问题,请在 Gitee 上提交 PR ,一起开源共建! -> 当前版本:`Release v1.00`,查看 [在线演示](http://flask.pearadmin.com/)。 +接下来,我们将会为您详细介绍该项目搭建方法与开发架构。 -![开始使用](README_files/1.jpg) +> **请注意:**Pear Admin Flask 项目有三个分支,请在阅读文档时,请注意辨别不同分支。 + +**[master分支版本](https://gitee.com/pear-admin/pear-admin-flask/tree/master/)** + +flask 2.0.1 + flask-sqlalchemy + 权限验证 + Flask-APScheduler 定时任务 + marshmallow 序列化与数据验证 + +master 分支为主分支,是功能最全、页面最多的分支。 + +**[mini 分支版本](https://gitee.com/pear-admin/pear-admin-flask/tree/mini/)** + +flask 2.0.1 + flask-sqlalchemy + 权限验证 + flask-restful + +此版本主要是提供一个最个简的 pear admin flask 快速开发的模板,可以帮助用户快速搭建一个后台管理系统。 +因为一些历史问题,例如 flask-restful 不再继续更新等,此版本不会也再继续更新,而会将精力投入到 main 分支当中去。 +如果想使用这个分支进行开发,可以看 https://www.bilibili.com/video/BV1FF411b7bS 进行学习。 + +**[main 分支版本](https://gitee.com/pear-admin/pear-admin-flask/tree/main/)** + +main 分支是对 mini 分支的后续,目前还在开发中。 + +![开始使用](README_files/1.jpg) ## 下载使用 :id=download @@ -26,3 +46,6 @@ Pear Admin Flask 基于 Flask 的后台管理系统,拥抱应用广泛的pytho ![源码仓库](README_files/2.jpg) + +如果您完成了这一步,请参阅[下载安装](install/)章节。 +