Bootstrap 5已彻底弃用jQuery,所有组件基于原生ES6实现;需仅引入bootstrap.min.css、@popperjs/core和bootstrap.min.js,推荐按需导入Modal、Tab等模块,并配合SortableJS实现看板拖拽,移动端采用offcanvas折叠列方案。

用 Bootstrap 5 构建看板式后台,别碰 jQuery
Bootstrap 5 已完全移除对 jQuery 的依赖,bootstrap.Modal、bootstrap.Dropdown 等组件全部基于原生 ES6。如果你还在项目里引入 jquery.slim.min.js,不仅白加一个 30KB 脚本,还会在调用 new bootstrap.Tab(...) 时因冲突导致初始化失败——尤其在拖拽看板列(如使用 SortableJS)时,事件监听器会静默失效。
正确做法是只加载三样东西:bootstrap.min.css、@popperjs/core(仅用于 tooltip/dropdown 定位)、bootstrap.min.js。Vite 或 Webpack 项目中推荐按需导入:
import 'bootstrap/dist/css/bootstrap.min.css';
import { Modal, Tab } from 'bootstrap';
这样能避免打包进未使用的组件代码,对后续集成看板拖拽逻辑更干净。
实现 Kanban 列拖拽,优先选 SortableJS 而非 Bootstrap DnD 插件
Bootstrap 本身不提供拖拽排序能力,官方文档也明确不维护 DnD 行为。硬用 data-bs-toggle="drag" 这类伪属性只会卡死或报 TypeError: Cannot read properties of null。
实际项目中,SortableJS 是最轻量、兼容性最好的选择(仅 8KB gzip)。它直接操作 DOM,与 Bootstrap 的 class 结构天然契合:
- 每列用
<div class="col-3"> 包裹,内部 <code><div class="card mb-2"> 作为任务卡片 <li>初始化时传入列容器的 <code>querySelectorAll('.kanban-column') - 监听
end事件,提取evt.from和evt.to的dataset.columnId,触发 API 更新任务状态 - 默认移动端只显示当前活跃列(比如
status="in-progress"),其余列收进<div class="offcanvas"> <li>顶部加一个 <code><button data-bs-toggle="offcanvas" data-bs-target="#column-selector"></button>触发列选择抽屉 - 抽屉内用
list-group显示各列标题,点击后用 JS 切换主内容区的data-column属性并重载卡片列表
注意:不要给卡片加 draggable="true" —— SortableJS 内部已处理,手动加会导致 Chrome 下出现双光标或拖拽偏移。
响应式看板在小屏上不是“缩放”,而是“折叠列+抽屉切换”
直接用 col-md-3 在手机上显示四列,结果每列只剩 80px 宽,卡片文字全折行、按钮挤成一条线——这不是响应式,是自欺欺人。
真实做法是:
这个模式在 Tabler、AdminLTE 等成熟后台模板中已验证可行,比强行网格堆砌更符合移动端操作直觉。
Django 后端连 MySQL 时,pymysql.install_as_MySQLdb() 必须写在 __init__.py 最顶上
看板数据要持久化,Django + MySQL 是常见组合。但 makemigrations 报错 ModuleNotFoundError: No module named 'MySQLdb' 不是因为没装 pymysql,而是因为 Django 在加载 settings 前就尝试 import 数据库驱动——此时 pymysql.install_as_MySQLdb() 还没执行。
必须确保项目根目录下 __init__.py 文件只有且仅有这两行:
import pymysql pymysql.install_as_MySQLdb()
多一个空行、少一个换行、或者被其他 import 挡在前面,都会让迁移命令当场失败。这不是可选项,是启动 Django 后端前的强制前置动作。


















