DC's blog DC's blog
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)

DC

愿我一生欢喜,不为世俗所及.
首页
  • 计算机基础
  • linux基础
  • mysql
  • git
  • 数据结构与算法
  • axure
  • english
  • docker
  • opp
  • oop
  • 网络并发编程
  • 不基础的py基础
  • 设计模式
  • html
  • css
  • javascript
  • jquery
  • UI
  • 第一次学vue
  • 第二次学vue
  • Django
  • drf
  • drf_re
  • 温故知新
  • flask
  • 前后端不分离

    • BBS
    • 订单系统
    • CRM
  • 前后端部分分离

    • pear-admin-flask
    • pear-admin-django
  • 前后端分离

    • 供应链系统
  • 理论基础
  • py数据分析包
  • 机器学习
  • 深度学习
  • 华中科大的网课
  • cursor
  • deepseek
  • 杂文
  • 罗老师语录
  • 关于我

    • me
  • 分类
  • 归档
GitHub (opens new window)
  • BBS

  • 订单平台

  • CRM

  • flask+layui

    • 初始化
      • 项目创建
        • 前端开发模版
        • 创建Flask项目
      • 静态文件初始化
        • ☆ 思考
        • 添加静态资源
        • 修改数据接口
      • 调整项目目录结构
      • config.py
      • 安装插件 (eg:db)
      • 注册蓝图结构优化
        • 蓝图少/多
        • 视图层和接口层
    • 数据库
    • 权限校验
  • django+layui

  • 供应链

  • 实战
  • flask+layui
DC
2024-09-25
目录

初始化

# 项目创建

# 前端开发模版

我们的项目是基于 pear admin layui 单页版进行开发..
Pear Admin 是一款开箱即用的前端开发模板!!

pear admin layui 单页版的gitee地址: https://gitee.com/pear-admin/Pear-Admin-Layui

image-20240925103224239

我们打开终端, cmd 到桌面, 执行上述命令 克隆项目到本地. <注意: 我们使用的是main分支 4.0.5的版本 看标签就知道了>

使用pycharm软件打开该项目, 简单看下项目的组成. (gitee上也有解释)

image-20240925104106978

接着, 我们在pychrm里打开终端, 试着运行该项目, 看看效果:
(PS: 其实直接执行index.html文件也可以看到效果,但我们还是专业点.

在项目根目录下,执行以下命令:
1> sudo cnpm install http-server -g
2> http-server . --port 8080

-- http-server 是一个非常简单的零配置的 HTTP 服务器,可以用于快速服务静态文件。
-- http-server . --port 8080
   http-server: 这个命令调用你刚刚安装的 HTTP 服务器程序
   . : 这个参数表示当前目录. 即服务器将会从当前目录提供文件服务
   --port 8080 : 指定端口
1
2
3
4
5
6
7
8
9

image-20240925105508765

# 创建Flask项目

利用pycharm使用虚拟环境创建一个新python项目 python版本3.9以上.. 命名为 pear_admin_flask

打开pychrm的终端,会自动进入虚拟环境.. 安装flask pip install flask

image-20240925111919386

在项目根目录下创建 app.py文件, 写入以下代码:

from flask import Flask


def create_app():
    app = Flask(__name__)

    @app.route('/')
    def index():
        return 'hello pear-admin-flask !'

    return app
1
2
3
4
5
6
7
8
9
10
11

在项目根目录下创建 .flaskenv 文件, 配置启动的环境指令:

FLASK_DEBUG=True                # 开启调试模式,值为True则可以热重载
FLASK_RUN_PORT=5001             # 设置运行的端口
FLASK_RUN_HOST=0.0.0.0          # 设置监听的 ip
FLASK_APP="app:create_app"      # 运行程序  我们创建的app.py所以这里是app 不配置它,默认也是app
1
2
3
4

在终端运行命令
pip install python-dotenv
flask run 启动项目.. (只有安装了python-dotenv,才会去项目根目录下读取 .flaskenv文件!!
该命令它背后会默认去找app.py里的create_app函数, 运行该函数, 拿到app对象, 执行 app.run()

image-20240925115119813


# 静态文件初始化

★★★ 简单来说..
-1- 纯前端模版就是 http://127.0.0.1:8080/路径 路径去项目根目录下找..
-2- Flask项目, 也是 http://127.0.0.1:8080/路径 但有区别.
     路径以static为前缀,证明去static目录下找静态文件(js、css、图片)..
     没有以static为前缀(eg: html), 则需进行路由匹配,执行相应视图函数!!

# ☆ 思考

首先想一下单纯运行前端开发模版时,它的执行过程

- 运行index.html 
  - <link rel="stylesheet" href="./component/pear/css/pear.css" /> 加载一系列静态资源
    >> http://127.0.0.1:8080/component/pear/css/pear.css
  - admin.setConfigurationPath("config/pear.config.yml"); 加载配置文件
    根据配置发送请求
    - image: "admin/images/logo.png"   去对应的路径下找到相应的静态资源
      >> http://127.0.0.1:8080/admin/images/logo.png
    - href: "view/analysis/index.html" 去对应的路径下运行html文件
      >> http://127.0.0.1:8080/view/analysis/index.html

这些请求去项目对应的路径下就可以直接找到!!
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              // 项目的静态页面目录
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

再思考下, 若将pear admin layui前端模版应用到 Flask项目中,如何做呢?

第一点: Flask的static目录 - 所有html和配置文件中的静态文件(css、js)的路径都要符合Flask的规则
第二点: Flask的templates目录 - 所有的html都要写 一个路由+一个视图函数!!
       ☆ 路由一般写成html在templates目录下的路径
       视图函数找到该html文件要符合Flask templates的规则!
      
- http://127.0.0.1:5001/ 路由匹配的视图函数返回浏览器index.html页面
- 浏览器渲染index.html页面时,发送请求
  - <link rel="stylesheet" href="/static/component/pear/css/pear.css" />
    >> http://127.0.0.1:5001/static/component/pear/css/pear.css 浏览器得到相应的css
  - admin.setConfigurationPath("/static/config/pear.config.json");
    >> http://127.0.0.1:5001/static/config/pear.config.json     浏览器得到配置文件的内容
- 浏览器加载配置文件pear.config.json里的内容
    根据配置发送请求
    - "image": "/static/admin/images/logo.png"
      >> http://127.0.0.1:5001/static/admin/images/logo.png
    - "href": "/view/console/index.html",
      >> http://127.0.0.1:5001/view/console/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 添加静态资源

我们需要将 pear admin layui 前端开发模版中的 一些文件夹 复制到 我们的Flask项目中!!

首先将 admin、component、config 三个目录复制到 static 目录下
然后将 index.html 、login.html 复制到 templates 目录中

在pychram中将templates目录右键标记为模版文件夹!!

image-20240925120715351

PS: 后续开发过程中需要什么就从前端模版中拿什么!!

接着, 我们需要修正下 html中引入文件的路径!

如何进行修正呢? 很容易想到, 因为 flask 项目默认会读取 static 目录下的静态文件, 且默认以/static为路径前缀..
所以我们只需要 在粘贴过来的html中 将所有静态路径的前面追加 /static/ ..

以index.html为例,eg:

<link rel="stylesheet" href="./component/pear/css/pear.css" />
修正成
<link rel="stylesheet" href="/static/component/pear/css/pear.css"/>


- 若重复在多个html中都用到了,可将这些路径放到 templates/includes/script.html 中,
  使用模版include语法,在index.html中这样写
<head>
    {% include 'includes/script.html' %}
</head>
1
2
3
4
5
6
7
8
9
10

# 修改数据接口

整体的流程在"思考"小节已经阐述清楚了, 在修改的过程中..
-1- 要学会打开控制台, 看网络, 哪些没请求到/没修改到..
-2- 修改完后,没有达到自己想要的效果, 点击页面上的退出/自己手动清除cookie和session等浏览器缓存.. 应该就可以解决!

image-20240925163839901


# 调整项目目录结构

可以先去官网看, pear admin flask 项目 main分支最终的成品..
项目地址: https://gitee.com/pear-admin/pear-admin-flask/tree/main/

image-20240926100849885

参照上面截图的目录结构 构建我们的项目的 小蓝图!!

-1- 在项目根目录下创建包pear_admin, 将原先app.py里的内容先剪切到这个包的__init__文件里.. 并删除app.py.
-2- 重新设置.flaskenv 里关于 FLASK_APP 的配置 FLASK_APP="pear_admin:create_app"
     因为pear_admin 是个包, 所以在cmd中运行 flask run 命令时, 会执行 pear_admin 包里 __init__ 里的内容!!
-3- 因为移动了create_app函数所在文件所处的位置, 所以得设置 app=Flask("pear_admin_pear").
     因为设置__name__ , 是以当前文件所在目录去找静态目录和模版目录; 我们在此需改为 以项目根目录为基准!!
-4- 在 pear_admin 下创建views目录, 该目录下的每个py文件都是一个小蓝图!!
     (相当于将原先app.py里的路由函数拆分到这一个个蓝图中!! 别忘了注册蓝图哦!
-5- 在 pear_admin 下再创建 apis、extensions、orms 文件夹, 先准备着, 以后会用!!

image-20240926104305038

# -- .flaskenv
FLASK_DEBUG=True                   # 开启调试模式,值为True则可以热重载
FLASK_RUN_PORT=5001                # 设置运行的端口
FLASK_RUN_HOST=0.0.0.0             # 设置监听的 ip
FLASK_APP="pear_admin:create_app"  # 运行程序  我们创建的app.py所以这里是app


# -- pear_admin/__init__.py
from flask import Flask
from .views.index import index_bp


def create_app():
    app = Flask("pear_admin_flask")

    app.register_blueprint(index_bp)
    return app


# -- pear_admin/views/index.py
from flask import Blueprint, render_template

index_bp = Blueprint('index', __name__)


@index_bp.route('/')
def index():
    return render_template('index.html')


@index_bp.route("/view/console/index.html")  # 工作台
def console():
    return render_template('view/console/index.html')


@index_bp.route("/view/analysis/index.html")  # 分析页
def analysis():
    return render_template('view/analysis/index.html')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38

# config.py

在编写项目的时候, 一般会运行在多种环境下, 为此最好是将配置文件进行统一..
比较好的方式是 使用类 进行继承 然后区分, 创建对象, 根据传递的参数再决定使用什么配置文件..

在项目根目录下创建config.py文件..

import os


class BaseConfig:
    SECRET_KEY = os.getenv('SECRET_KEY', 'pear-admin-flask')

    SQLALCHEMY_DATABASE_URI = ""


class DevelopmentConfig(BaseConfig):
    """开发配置"""
    SQLALCHEMY_DATABASE_URI = "sqlite:///pear_admin.db"
    SQLALCHEMY_TRACK_MODIFICATIONS = False


class TestingConfig(BaseConfig):
    """测试配置"""
    SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'  # 内存数据库


class ProductionConfig(BaseConfig):
    """生成环境配置"""
    SQLALCHEMY_DATABASE_URI = "mysql://root:[email protected]:3306/pear_admin"
    SQLALCHEMY_TRACK_MODIFICATIONS = False


config = {
    'dev': DevelopmentConfig,
    'test': TestingConfig,
    'prod': ProductionConfig
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

然后在 pear_admin/__init__.py 中添加配置

from flask import Flask
from .views.index import index_bp
from configs import config  # 导入配置文件


def create_app(config_name='dev'):
    app = Flask("pear_admin_flask")
    app.config.from_object(config[config_name])  # 加载配置文件
    # print(app.config.get("SQLALCHEMY_DATABASE_URI"))

    app.register_blueprint(index_bp)
    return app
1
2
3
4
5
6
7
8
9
10
11
12

★ 当我们启动项目之前, 想用哪个配置, 就去.flaskenv 改下. 选一个就好,不传参默认是dev..

FLASK_APP="pear_admin:create_app"
FLASK_APP="pear_admin:create_app('dev')"
FLASK_APP="pear_admin:create_app('test')"
FLASK_APP="pear_admin:create_app('prod')"
1
2
3
4

# 安装插件 (eg:db)

安装我们这个Flask项目所需要用到的 第三方组件/插件..

image-20240926113532121

pip install flask-sqlalchemy. pip install flask-migrate

初始化数据库插件

# -- pear_admin/extensions/init_db.py
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy

# - 初始化数据库相关插件
db = SQLAlchemy()    # ORM操作数据库
migrate = Migrate()  # 数据库迁移
1
2
3
4
5
6
7

封装到拓展插件目录

# -- pear_admin/extensions/__init__.py
from flask import Flask

from .init_db import db, migrate


# 将初始化的插件对象,封装此处
def register_extensions(app: Flask):
    db.init_app(app)
    migrate.init_app(app, db)
1
2
3
4
5
6
7
8
9
10

在 app 中配置

from flask import Flask
from .views.index import index_bp
from configs import config  # 导入配置文件
from pear_admin.extensions import register_extensions  # +


def create_app(config_name='dev'):
    app = Flask("pear_admin_flask")

    app.config.from_object(config[config_name])  # 加载配置文件
    # print(app.config.get("SQLALCHEMY_DATABASE_URI"))

    register_extensions(app)  # + 注册插件

    app.register_blueprint(index_bp)  # 注册蓝图
    return app
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 注册蓝图结构优化

# 蓝图少/多

若蓝图比较少, 可以这样做:

image-20240926120134691

若蓝图很多, 可以这样做: (以包的形式去初始化蓝图

image-20240926121010993

# 视图层和接口层

项目的蓝图还可以分为 视图层和接口层..
请求返回 HTML 的路由全部走视图层, 返回的是 json 数据的全部走接口层!!

image-20240926134410159

运行 flask routes 就可以看到显示出来的内容..

(.venv) MacBook-Air:pear_admin_flask dengchuan$ flask routes
Endpoint             Methods  Rule                     
-------------------  -------  -------------------------
api.passport.login   POST     /api/v1/login            
api.passport.logout  POST     /api/v1/logout           
index.analysis       GET      /view/analysis/index.html
index.console        GET      /view/console/index.html 
index.index          GET      /                        
static               GET      /static/<path:filename>  
1
2
3
4
5
6
7
8
9

目标:将项目上传到gitee上.
- 在gitee上创建同名项目
- 在本地项目中添加 忽略文件.. 提交、推送. 基于http的推送会让你输入用户名密码,正确就推送成功
- 因为是自己一个人维护,所以往后推送以前先拉取!!
1
2
3
4

提一嘴, 上面关于包的应用 其实就是下面这段代码的封装

from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)

"""
config.py
"""
class Config:
    # 数据库链接配置参数
    SQLALCHEMY_DATABASE_URI = 'sqlite:///data_04.db'
    SQLALCHEMY_TRACK_MODIFICATIONS = False
    # SQLALCHEMY_ECHO = True
    SECRET_KEY = 'secret key'


app.config.from_object(Config)

"""
插件 - ORM和数据库迁移相关
"""
# 创建数据库链接对象
db = SQLAlchemy()
migrate = Migrate()
db.init_app(app)
migrate.init_app(app, db)


class Student(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(length=20))
    gender = db.Column(db.String(length=20))
    birth = db.Column(db.String(length=20))
    phone = db.Column(db.String(length=20))

    def __repr__(self):
        return '<Student %s>' % self.name

"""
蓝图 - 分为两类<视图和接口>
"""
@app.route('/')
def index():
    return render_template('index.html')
  
  
@app.post('/login')
def login():
    return {'message': '登陆成功', 'code': 200}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

权限应用
数据库

← 权限应用 数据库→

最近更新
01
deepseek本地部署+知识库
02-17
02
实操-微信小程序
02-14
03
教学-cursor深度探讨
02-13
更多文章>
Theme by Vdoing | Copyright © 2023-2025 DC | One Piece
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式