pear admin flask 初始化
flask 项目创建
提示
如果不了解虚拟环境的,可以查看 poetry 入门完全指南
初始化
poetry init
在当前项目目录下创建虚拟环境
poetry config virtualenvs.in-project true
poetry add flask
新建程序实例
from flask import Flask
def create_app():
app = Flask(__name__)
@app.route('/')
def index():
return 'hello pear-admin-flask !'
return app
开发模式下用以下指令安装依赖
poetry add python-dotenv --group dev
提示
生产环境下使用
poetry install --no-dev
不会安装开发组的依赖
启动的环境指令为下
FLASK_DEBUG=True # 开启调试模式
FLASK_RUN_PORT=5050 # 设置运行的端口
FLASK_RUN_HOST=0.0.0.0 # 设置监听的 ip
FLASK_APP="apps:create_app()" # 运行程序
之后进入虚拟环境(poetry shell
),使用 flask run
就可以启动程序。
静态文件初始化
将 pear admin layui 的静态文件复制到项目目录下,并且使用样式启动整个项目。
可以在 pear.config.json
中可以修改主配色
添加静态资源
前端项目地址: https://gitee.com/pear-admin/Pear-Admin-Layui
项目的内容有时候无法保持最新的更新,使用的时候请注意版本是否正确。
首先下载 pear-admin-layui 的项目源码,然后切换到单页版的内容(编写此文档时还是4.x版本),后续可能已经更新到主分支中。
目录的大致结构如下
D:.
│ index.html
│ LICENSE
│ login.html
│ README.md
│ register.html // 注册页
├─admin
│ ├─css // css 样式存放位置
│ ├─data // 数据存放位置
│ └─images // 静态图片存放位置
├─api // 测试接口数据存放位置
│
├─component
│ ├─layui // layui 文件
│ └─pear
│ │ pear.js // pear admin layui 的核心 js
│ ├─css // 项目的核心样式
│ ├─font
│ └─module // 项目的核心模块目录
│ │
│ └─extends // 拓展模目录
│
├─config // 项目初始化加载的配置文件
│ pear.config.json
│ pear.config.yml
│
└─view // 项目的静态页面目录
然后将 admin
、component
、config
三个目录复制到 static
目录下
然后将 index.html
复制到 templates
目录中
首先需要修正一下引入的文件路径。因为 flask
项目的静态文件均放在 static
目录下,所以需要在之前所有的静态路径之前追加 /static/
复制进去之后,将项目中会用到的外源 css、js ,如果使用后端服务器渲染(SSR),可以都都抽取到 templates/includes/script.html
中
<link rel="stylesheet" href="/static/component/pear/css/pear.css"/>
<link rel="stylesheet" href="/static/admin/css/admin.css"/>
<link rel="stylesheet" href="/static/admin/css/admin.dark.css"/>
<link rel="stylesheet" href="/static/admin/css/variables.css"/>
<link rel="stylesheet" href="/static/admin/css/reset.css"/>
<!-- 依 赖 脚 本 -->
<script src="/static/component/layui/layui.js"></script>
<script src="/static/component/pear/pear.js"></script>
然后在 index.html 引入使用
<head>
{% include 'includes/script.html' %}
</head>
这里我们选择前后端分离的方式,就需要在每个页面中自己手动添加引入的完整路径,而不能交给后端进行渲染。
修改接在数据接口
然后翻到最后,修改从后端加载前端配置文件的接口
<script>
layui.use(["admin", "jquery", "popup"], function () {
var $ = layui.jquery;
var admin = layui.admin;
var popup = layui.popup;
admin.setConfigurationPath("config/pear.config.yml");
admin.setConfigurationPath("/static/config/pear.config.json");
...
</script>
pear admin layui 就是从后端加载接口数据,然后渲染前端页面的。可以将数据从静态文件中返回,也可以自定义接口进行返回。 使用自定义接口可以将数据存储在数据库中,修改之后动态生成前端页面数据。
暂时先把项目调通,所以修改一下 /static/config/pear.config.json
的几个路径
{
"logo": {
"title": "Pear Admin",
"image": "admin/images/logo.png",
"image": "/static/admin/images/logo.png",
},
"menu": {
"data": "admin/data/menu.json",
"data": "/static/admin/data/menu.json",
"method": "GET",
"accordion": true,
"collapse": false,
"control": false,
"controlWidth": 500,
"select": "10",
"async": true
},
"tab": {
"enable": true,
"keepState": true,
"session": true,
"preload": false,
"max": "30",
"index": {
"id": "10",
"href": "view/analysis/index.html",
"title": "首页"
}
},
"theme": {
"defaultColor": "2",
"defaultMenu": "dark-theme",
"defaultHeader": "light-theme",
"allowCustom": true,
"banner": false,
"dark": true
},
"colors": [
{
"id": "1",
"color": "#16baaa",
"second": "#ecf5ff"
},
{
"id": "2",
"color": "#009688",
"second": "#ecf5ff"
},
{
"id": "3",
"color": "#36b368",
"second": "#f0f9eb"
},
{
"id": "4",
"color": "#f6ad55",
"second": "#fdf6ec"
},
{
"id": "5",
"color": "#f56c6c",
"second": "#fef0f0"
},
{
"id": "6",
"color": "#3963bc",
"second": "#ecf5ff"
}
],
"other": {
"keepLoad": "1200",
"autoHead": false,
"footer": false
},
"header": {
"message": "admin/data/message.json"
"message": "/static/admin/data/message.json"
}
}
其中 menu.json 的内容如下
[
{
"id": 1,
"title": "工作空间",
"icon": "layui-icon layui-icon-console",
"type": 0,
"children": [
{
"id": "10",
"title": "分析页",
"icon": "layui-icon layui-icon-console",
"type": 1,
"openType": "_component",
"href": "view/analysis/index.html"
},
{
"id": "11",
"title": "工作台",
"icon": "layui-icon layui-icon-console",
"type": 1,
"openType": "_component",
"href": "view/console/index.html"
}
]
}
]
然后复制静态页面到 templates 项目之中,复制完之后的目录如下
templates:.
│ index.html
│ login.html
│ register.html
├─includes
│ script.html
└─view
├─analysis
│ index.html
└─console
index.html
然后完善蓝图部分
from flask import Blueprint, render_template
index_bp = Blueprint('index', __name__)
@index_bp.route("/")
def index():
return render_template('index.html')
@index_bp.route("/login.html")
def login():
return render_template('login.html')
@index_bp.route("/register.html")
def register():
return render_template('register.html')
@index_bp.route("/view/console/index.html")
def console1():
return render_template('view/console/index.html')
@index_bp.route("/view/analysis/index.html")
def analysis():
return render_template('view/analysis/index.html')
代码校验
poetry add pre-commit --group dev
touch .gitignore
.idea/
.venv/
*.py[cod]
新增 .pre-commit-config.yaml 文件,添加下面内容
repos:
- repo: https://github.com/python/black
rev: 23.9.1
hooks:
- id: black
language_version: python3.10
- repo: https://github.com/pycqa/isort
rev: 5.12.0
hooks:
- id: isort
args: [ "--profile", "black", "--filter-files" ]
- repo: https://github.com/pre-commit/mirrors-prettier
rev: "v3.0.3"
hooks:
- id: prettier
exclude: >
(?x)^(
.*.yaml|
package-lock.json|
yarn.lock|
^.+\.min\.(js|css)$
)$
stages: [ commit ]
代码提交校验
使用 commitizen 格式化 commit message
自定义提交校验
.cz.toml
[tool.commitizen]
name = "cz_customize"
tag_format = "$version"
version_scheme = "pep440"
version_provider = "poetry"
update_changelog_on_bump = true
major_version_zero = true
[tool.commitizen.customize]
message_template = "{{change_type}}{% if scope %}({{scope}}){% endif %}:{% if subject %} {{subject}}{% endif %} {% if footer %} {{footer}}{% endif %}"
example = "feature: this feature enable customize through config file"
schema = "<type>: <body>"
schema_pattern = "(feature|fix|docs|style|refactor|perf|test|revert|build).*?:(\\s.*)"
bump_pattern = "^(break|new|fix|hotfix)"
bump_map = { "break" = "MAJOR", "new" = "MINOR", "fix" = "PATCH", "hotfix" = "PATCH" }
change_type_order = ["BREAKING CHANGE", "feat", "fix", "refactor", "perf"]
info_path = "cz_customize_info.txt"
info = """
This is customized info
"""
commit_parser = "^(?P<change_type>feature|fix|docs|style|refactor|perf|test|revert|build).*?:\\s(?P<message>.*)?"
changelog_pattern = "^(feature|fix|docs|style|refactor|perf|test|revert|build)?(!)?"
change_type_map = { "feature" = "Feat", "bug fix" = "Fix" }
# 自定义提交指令
[[tool.commitizen.customize.questions]]
type = "list"
name = "change_type"
choices = [
{ value = "feature", name = "feature: 新功能" },
{ value = "fix", name = "fix: 修复 bug" },
{ value = "docs", name = "docs: 文档的修改" },
{ value = "style", name = "style: 格式化变动,不影响代码逻辑" },
{ value = "refactor", name = "refactor: 重构,即不是新增功能,也不是修改 bug 的代码变动" },
{ value = "perf", name = "perf: 性能优化" },
{ value = "test", name = "test: 增加测试" },
{ value = "revert", name = "revert: 回退" },
{ value = "build", name = "build: 打包" },
]
# choices = ["feature", "fix"] # short version
message = "请选择提交类型:"
# 修改内容的范围
[[tool.commitizen.customize.questions]]
type = "input"
name = "scope"
message = "请输入修改内容的范围(可选):"
# 自己的提交内容
[[tool.commitizen.customize.questions]]
type = "input"
name = "subject"
message = "请输入简要描述(必填):"
# 自己的提交内容
[[tool.commitizen.customize.questions]]
type = "input"
name = "body"
message = "请输入详细描述(可选):"
[[tool.commitizen.customize.questions]]
type = "input"
name = "footer"
message = "请输入需要关闭的 issue(可选):"
追加到 .pre-commit-config.yaml
- repo: https://github.com/commitizen-tools/commitizen
rev: 3.5.3
hooks:
- id: commitizen
stages: [ commit-msg ]