如何用拖放在Flask看板应用中更新数据库状态
本文深入解析在 Flask + Jinja2 构建的看板系统中,如何巧妙运用 HTML5 Drag and Drop API 与后端逻辑联动,实现任务卡片跨列(to-do / in progress / done)拖拽时即时更新数据库状态。同时重点剖析事件未触发、子元素干扰、服务端函数误执行等典型陷阱及对应解决方案。
在 Flask + Jinja2 搭建的看板应用中,如果你尝试让任务卡片跨列拖拽后自动更新数据库,大概率会踩进同一个坑:以为在 drop 事件里直接调用 {{ dropped(...) }} 就行。但事实是,Jinja2 模板中的这组花括号语法,在页面渲染到浏览器之前就已经被服务端计算完毕——它并非 JavaScript 函数,不会等你拖拽结束再执行。所以很多人的实现就直接“趴窝”了。
那该怎么办?我们先厘清一个非常常见的误区:
✅ 正确思路不是让模板去调后端,而是通过前端 fetch() 向 Flask 路由发送一条异步 POST 请求,把拖拽的 task_id 和 target_state 打包成 JSON 发给后端;后端收到后更新数据库、提交事务,然后返回一个重定向响应。
✅ 前端实现:给容器绑定事件,而非子元素
在结构上,ondrop、ondragover 这类事件必须绑定在 容器(即 drop zone)上,并通过 this 把当前容器传入函数。这样做主要是为了避免事件被 或其中的 、 等子元素截胡。以下模板结构经过实践验证:
To-Do
{% for (depth, pending) in tasks_by_status[1] %}- {% endfor %}
{{ pending.description }}
对应的 JavaScript 部分,需要用一个计数器来防止子元素进入/离开时反复触发样式变化,同时用 fetch 把拖放数据送到后端:
⚠️ 千万别忽略
ondragover里的ev.preventDefault(),这是 drop 事件能够触发的先决条件。另外,在dragEnter/dragLea ve中添加ev.stopPropagation()可以避免子元素打断计数逻辑。
✅ 后端实现:用单一路由同时处理 GET 和 POST
Flask 端的实现并不复杂,关键在于区分普通表单提交和 JSON 拖放请求。前者走 request.form,后者走 request.json。更新完任务状态后在 session 中提交,然后重定向回当前看板——以下代码最为清晰:
@main.route("//kanban", methods=["GET", "POST"])def kanban(project_id): project = Project.query.get(project_id) if not project: return render_template("404.html"), 404 try: session = sessions_by_project[project_id] except KeyError: return render_template("404.html"), 404 tasks_by_status = defaultdict(list) for depth, task in walk_list(session.query(Task).all()): tasks_by_status[task.status.value].append((depth, task)) # 普通表单提交(例如点击任务按钮) if request.method == "POST" and "task" in request.form: return redirect(url_for("main.task", project_id=project_id, id=int(request.form["task"]))) # 拖放 JSON 更新 if request.method == "POST" and request.is_json: data = request.get_json() if "task_id" in data and "target_state" in data: task_id = int(data["task_id"]) target_state = data["target_state"] task = session.query(Task).get(task_id) if not task: return render_template("404.html"), 404 task.change_status(str2status(target_state)) session.commit() return "", 204 return render_template("kanban.html", tasks_by_status=tasks_by_status, project=project)
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
如何用拖放在Flask看板应用中更新数据库状态
在Flask看板应用中,通过HTML5拖放API结合前端fetch异步POST请求,将拖拽任务的task_id和target_state发送至后端路由;后端接收JSON后更新数据库并提交事务,实现跨列拖拽时实时更新状态。需注意将事件绑定到容器而非子元素,并在ondragover中阻止默认行为以确保drop触发。
如何用CSS :has()选择器快速实现悬停span显示相邻div
利用CSS的:has()伪类选择器,通过` bar:has(> baz:hover)+ qux`实现悬停内联元素时显示相邻块级容器,解决了传统相邻兄弟选择器无法跨层级匹配的局限,可用于悬停图标显示详情框等交互场景。需注意浏览器兼容性和性能优化,避免过度使用影响渲染效率。
display:block居中段落文本的响应式实现方法
通过`display:block`与`max-width`限制宽度,配合`margin:auto`使段落块水平居中并实现响应式布局;同时用CSS统一控制段落间距,避免脱离文档流,提升可读性与维护性。
JavaScript代码去重:高效避免重复编写的技巧
将重复代码中的变化点提取为参数,利用ES6模板字符串动态生成选择器,可消除重复、保持一致性。注意参数安全性,必要时进行白名单校验;批量化场景可扩展为数组形式;现代框架中更推荐数据驱动或组件化封装替代手动选择器。
使用容器查询单位cqw实现表单输入框相对于祖父容器百分比宽度
利用CSS容器查询单位cqw,表单输入框宽度可直接基于祖父容器计算,绕过中间包装器尺寸干扰,实现简洁响应式布局,无需硬编码或JavaScript,显著降低维护成本,提升嵌套结构下的布局灵活性。
- 日榜
- 周榜
- 月榜
相关攻略
2026-07-09 07:01
2026-07-09 07:01
2026-07-09 07:00
2026-07-09 07:00
2026-07-09 07:00
2026-07-09 07:00
2026-07-09 07:00
2026-07-09 06:59
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

