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

  • django+layui

    • 理论储备
    • 项目编写
      • 项目创建
      • 引入前端模版
      • 项目数据表的设计
      • rbac模块
      • layui前端框架
      • pear admin前端模版
    • 规则怪谈
    • 一些思考
    • 代码讲解
    • 部署
  • 供应链

  • 实战
  • django+layui
DC
2024-11-11
目录

项目编写

image-20241111084919207


# 项目创建

  • 创建python项目 pear_admin_django , 并用poetry创建虚拟环境..

  • poetry add django==3.2 将项目变成django项目

    • 创建了三个app - base、rbac、systems

      • base放所有的数据表、rbac实现基于角色权限、systems 业务系统.
      • 记得修改下每个app的apps.py
        • 项目根目录下创建apps文件,将base放到里面
        • 记得将 apps/base/apps.py 里的 name = 'base' 改为 name = 'apps.base'
        • 注册app 'apps.base.apps.BaseConfig',
      • 配置Django项目的快速启动, 在settings.py里注册app时就会有提示了!
    • 基于全局变量的形式配置settings文件.. (若是Flask还可以基于类的形式)

      • 在settings.py的最后写代码

        try:
            from .local_settings import *
        except ImportError:
            pass
        
        1
        2
        3
        4
      • 在settings.py的同级目录下创建 local_settings.py 文件. (线上服务器也需建立它,自己写线上的配置

    • 在项目根目录下添加忽略文件. .gitignore

      .idea/
      .venv/
      __pycache__/
      migrations/
      node_modules
      zdc_test/
      
      *.py[cod]
      *$py.class
      
      .DS_Store
      **/.DS_Store
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
  • 在项目根目录下创建static和templates文件夹..

  • 将项目上传到gitee中, 进行代码的管理.

    在gitee上创建项目后 在终端输入以下命令
    git init 
    git remote add origin https://gitee.com/One_PieceDC/pear_admin_django.git
    git add .
    git commit -m "第一次提交,项目初始化"
    git push origin main
    
    提交远端时没报错,但远端也没更新,看打印输出: fatal: the remote end hung up unexpectedly
    这是因为提交远端的文件太大,执行命令: git config --local http.postBuffer 524288000
    
    1
    2
    3
    4
    5
    6
    7
    8
    9

目前, 项目的结构树长这样!

pear_admin_django
├── .venv
├── apps
│   ├── base
│   ├── rbac
│   └── system
├── db.sqlite3
├── manage.py
├── pear_admin_django
│   ├── asgi.py
│   ├── local_settings.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── poetry.lock
├── pyproject.toml
├── static
└── templates
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 引入前端模版

不要急,慢慢搞的. 返回index.html首页的视图函数是切入点,然后按照 前端模版的运行逻辑逐步去完善!
在总路由里写路由和视图,先验证对不对,然后将 路由和视图 放到rbac这个app下不同的业务文件夹中!

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

  • 后端引入前端模版,进行静态文件的初始化

    • 前端模版自己单独运行时

      • 构建url -- 协议+域名+端口 [拼接] 写的路径, 浏览器根据url地址发送请求
      • 项目根据路径在项目目录上直接找html、css、js、png, 并返回
      - ☆ 前端模版的运行逻辑
        - 双击index.html,用浏览器打开
        - 浏览器执行index.html中这行代码时admin.setConfigurationPath("config/pear.config.json");
          浏览器会加载配置文件pear.config.json里的内容
        - pear.config.json 里根据配置发送请求 eg: "image": "admin/images/logo.png"
      
      在html、json等文件中只要看到路径,不管是html模版还是css、png其它静态资源,都是直接拼接的. 
      > href="./component/pear/css/pear.css" -- http://127.0.0.1:8080/component/pear/css/pear.css
        image: "admin/images/logo.png"  --  http://127.0.0.1:8080/admin/images/logo.png
        href: "view/analysis/index.html"  --  http://127.0.0.1:8080/view/analysis/index.html
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
    • 后端引入前端模版

      • 构建url -- 协议+域名+端口 [拼接] 写的路径, 浏览器根据url地址向 [后端] 发送请求
      • 若请求的资源是css、js、png, 后端会根据静态文件的查找规则在项目目录结构中直接找,不需要视图函数
      • 若请求的资源是html, 就得经过视图函数返回对应的html模版,当然,返回的html也得遵循模版查找规则
      • 什么查找规则呢?
  • 后端Django对于html、css、js、png的查找规则

    • 简单来说, 模版不需要templates前缀(但需要走视图函数的逻辑),在 [templates目录下] 找写的路径.
      css, js, png [需要static前缀](表明不需要视图函数), 在 [static的上级目录下] 找写的路径..

    • 模版的查找顺序

      比如视图函数 return render(request, 'view/analysis/index.html')
      
      'DIRS': [os.path.join(BASE_DIR, 'templates')],  # 可去该路径下找'view/analysis/index.html'模版文件
      'APP_DIRS': True                                # 可去注册的app路径下找到templates目录,在该目录下找模版文件
      
      1
      2
      3
      4
    • Img、css、js的查找顺序

      STATIC_URL = '/staic/'  # 前缀
      STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'), ]  # 去哪找
      
      !!基于上述的配置!!(这是前提
      """
      STATIC_URL必须得有.
      1  根据 <img src='/static/web/1.png'> 得到url 
      2. 浏览器根据url发送请求 http://127.0.0.1:8000/static/web/1.png
      3. 服务器优先在项目根目录下找路径 /static/web/1.png;
         若没找到就按注册顺序去已注册的app下找路径 /static/web/1.png
      
      ★ 经验:多app的情况,会在app的templates、static目录下再嵌套一层命名为app名字的目录.该目录下放模版!!
      """
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
    • 具体操作

      • 将前端模版 pear admin layui中的 admin、component、config 三个目录复制到后端的 static 目录里

      • 将前端模版 pear admin layui中的 view 目录复制到 后端的 templates 目录里

      • 将前端模版 pear admin layui中的 index.html 、login.html 复制到 templates 目录中

      • 进行静态文件里路径的修改, 举例 (浏览器控制台的网络可以看是否改正确

      <link rel="stylesheet" href="./component/pear/css/pear.css" />
      修正成
      <link rel="stylesheet" href="/static/component/pear/css/pear.css"/>
      /component/pear/css/pear.css 放在后端项目根目录下的staic文件夹里!!
      
      pear.config.json里 "href": "view/analysis/index.html" 保持原样,懒得改了!
      > 就按照http://127.0.0.1:8080/view/analysis/index.html发送请求
        写个名为/view/analysis/index.html的路由,进行路由匹配
        匹配的视图函数 return render(request, 'view/analysis/index.html') 返回index.html
        将index.html放在后端项目根目录下的templates/view/analysis文件夹里
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
    • 可以在 index.html 中给 html 标签添加 lang='zh-CN', 每次刷新时就不会弹出翻译提示了 + 时区的设置


# 项目数据表的设计

image-20241016102519304

  • ORM的编写必须在app中, 用名为models的包来实现, 将原本写在models.py中的ORM表拆分成一个个的py文件.

    关于ORM表,也拆分到了一个个py文件中,还根据来自不同的app,放在了不同的文件夹中 
    因为使用了包,所以在调用上跟 这些py文件放在同一个文件夹下 没差别!! 但代码更清晰一点!
    - 思考?若rbac的用户表满足不了,systems中自己弄个用户表. 
      方案一 一对一外键, 一张表的字段被拆分到了两表中,不妥
      方案二 继承+abstract = True 让rbac中的用户表迁移时不生成表
      方案三 你直接使用rbac的用户表 对其进行更改,使其满足systems的标准. 这种更方便!!
    
    1
    2
    3
    4
    5
    6
  • ORM代码编写完后, 启动mysql数据库, 执行命令进行数据库的迁移..

    • 在pycharm中连接mysql数据库后.
      在mysql的终端, 执行命令 create database pear_admin_django character set utf8mb4;
    • 在Django中local_setting.py中进行mysql的配置, 开始数据库的迁移.
  • 用脚本批量添加测试数据

    name,age,sex
    x,,10
    y,,22
    
    csv文件中 某个字段值没写 模拟的就是表单中有该字段,但该字段没填??Hhh
    
    1
    2
    3
    4
    5

# rbac模块

关于rbac, 基于角色的用户权限管理系统.. 我大体分为了5个模块, 登陆、部门管理、权限管理、角色管理、用户管理..

这些功能的实现更重要的是想清楚有哪些需求, 用怎样的技术实现更合适, 代码编写反而不是最难的..
各个模块的需求详看规则怪谈..


# layui前端框架

下面我们来康康利用layui前端框架, 帮助我在项目开发过程中, 解决了哪些通用性的问题, 以便往后遇到类似需求可复用..

[主页]

1. 解决了树形表格中根据排序字段的大小实现列表数据排序的问题
2. 解决了树形表格中的全部折叠和全部展开 -- To do: 若指定到第几层如何实现,待解决.
3. 解决了表格中,数据样式的问题. by templet属性 + es6语法 
   eg: 根据值的不同,展示对应的`菜单`、`节点`、`权限`的徽章
4. hide:True 可以让该列在表格中自动隐藏,当然可以在主页表格中选择展示哪些列.
5. 一行table标签,数据通过layui的组件自动渲染
   - 头部工具栏 > 新增的iframe、全部折叠、全部展开
   - 行工具栏 > 编辑的iframe<需实现自动填充表单>、删除
6. 启动|禁用按钮的复选框事件 - 注: 某个权限的禁用会影响动态菜单的展示以及中间件里权限的鉴定
7. 在ORM表的json方法中实现了日期数据的处理!
8. 日期范围的选择!
1
2
3
4
5
6
7
8
9
10
11

[新增、编辑 的表单]

1. 实现了 选择不同的单选框,在表单中显示隐藏不同的表单项 - <单选框事件“监听类型切换”>
2. 实现了 表单中,鼠标悬浮在表单项上,会有提示的功能.
3. 权限模块的新增编辑页面,解决了图标选择问题
   -- https://gitee.com/wujiawei0926/iconpicker
4. 权限模块的新增编辑页面,解决了下拉框选择问题(下拉展示的是权限树
   -- https://gitee.com/honestno1/combotree
>> 关于3、4 我直接添加到了pear里面!!
5. 解决了图标选择、下拉框单选、下拉框展示树、单选框 在编辑页面的表单里默认选择的问题!!
6. 权限模块 对权限实现了软删除. 部门、用户、角色同理!
1
2
3
4
5
6
7
8
9

[授权 树]

1. 利用了 tree 组件,实现了对角色授权!
1

[其它]

1. X_FRAME_OPTIONS = 'SAMEORIGIN'  # 避免'X-Frame-Options' to 'deny' 的报错! 解决弹窗被浏览器劫持问题
2. 解决CSRF
   let token = "{{ csrf_token }}";
   $.ajaxSetup({
     headers: {'X-CSRFTOKEN': `${token}`},
   });
1
2
3
4
5
6

# pear admin前端模版

[一些注意事项]

1. 基于combotree实现的树,返回的json数据中名字相关的字段只能叫做name,若是title,它识别不了.
   combotree组件render时,data是接收静态数据,ajaxUrl才是发送ajax请求的参数.
   <实践过程中,报了个错 说在pear中找不到combotree组件的的treetable依赖,放进去就好.不要纠结为啥!
   >> ★★★ 后来,我直接添加到了pear里面!!
2. 实现动态菜单时,规定了是名为type字段,其值的含义可想象成0是目录,1是文件; 地址规定了是名为href的字段
3. pear.config.json里,首页对应的默认选中的菜单的ID一定要设置正确!!
4. {{ edit_obj.pid_id|default:'' }}  数据库中字段值为null,前端会显示None,当None时我们让前端显示为空
1
2
3
4
5
6
7

[一些思考或待解决或尝试过无果的问题]

1. _blank的形式打开节点,需要加载下layui.js
   若添加后,默认的内部打开的节点,会因为添加了layui.js而出现样式错误 (挺奇怪的
   若改为添加layui.js和pear.js,控制台会报错,重复加载模块组件的错误.
   > 尝试解决无果,我觉得全部都选择默认的内部打开即可!!
   !!! 后续我解决了这个问题 内部打开不要用_component,要用_iframe
2. 想着自动发现路由,改写下源码,给path加上text属性,但想想还是算了,暂时没必要折腾这个!
3. 半分离的编辑参照不分离的编辑的逻辑,按道理在返回编辑页面之前,不仅要实现表单数据的自动填充,
   还得判断该id是否有对应的对象,我思考了下:
   url上没有?params参数,request.GET.get('id')值为空, filter first后也为空,展示的编辑表单都为空,无伤大雅!
4. 动态菜单函数添加一个超级用户判断,使得添加新权限后,超级用户不用给自己授权,就能刷新展示新的菜单?? 
   没必要,superman老老实实给自己授权就好.
5. 若我在右上角的头像的下拉菜单里,添加了"个人中心"的选项,它不用引入css、js,用的就是index.html里的.
   而且你若引入了,左侧的动态菜单的展开关闭的js动画会抽搐.
   而为了后面能给角色授权,个人中心相关的几个url也要一并写在权限中,意味着它也会出现在动态菜单中!!
   出现在动态菜单中的话,这个个人中心的页面就得添加js、css..
   前后的分析需求是矛盾的,不能同时实现. > 解决方案:在头像下拉中只保留注销选项,个人中心的选项删除掉!让个人中心出现在动态菜单里.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

pear admin layui 的开源项目中有 柱状图、折线图 的模版, 需要时可以去参考..
加载的配置文件,每个配置项啥意思, 参考 https://gitee.com/pear-admin/pear-admin-flask/blob/master/applications/view/system/rights.py

[主页]
To do: 若n:n,后端ORM表的json方法将对应字段处理下,前端再自行处理下.
To do: 组合搜索
  
    
[新增、编辑 的表单]
6. To do:权限模块 新增编辑时 对于权限的标识和url与系统中的是否匹配?! (因为这东西涉及权限校验,马虎不得.
   下拉框展示可添加的节点、权限的URL和标识?没有则显示暂无可添加的节点和权限?
   > 菜单-权限管理,一般开发完就不会动了,所以需要开发一个接口扫描功能吗??没必要吧!!
  
[其它]
2. To do: 短信验证码登陆?
3. To do: 将pear.config.json的配置的获取改为接口,而不是直接加载json文件?
  
  
- 该角色分配给了其他用户使用,无法删除!
- 权限那里是否开启 除了超级管理员,哪怕给某个角色分配了该权限,该权限没有开启也不会生效!!
- 用户那里账号不可用的话,是登陆不了的!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

to -1 -2 -3 还是在seccess里弄..

完善下登陆认证和权限认证.. 整理下需求和已完成的功能出来..

    form = UserAddForm(request.POST)
    my_l = []
    for name, field in form.fields.items():
        print(name, field)
        my_l.append(name)
    print(my_l)
    if not form.is_valid():
        return res_json_data.no_valid_api(form)
1
2
3
4
5
6
7
8
理论储备
规则怪谈

← 理论储备 规则怪谈→

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