You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中获取HTML拖拽放置元素的值?

解决拖拽练习到盒子后无法在Flask后端获取值的问题

问题出在表单提交的规则上:

  • 你拖拽的<a>标签是普通HTML元素,不是表单专属控件(比如input、select),表单提交时只会发送表单控件的值,不会处理这些普通元素。
  • 给盒子<div>加的name属性无效,只有表单控件的name才会被表单识别,所以后端request.form.get("C")拿不到任何值,返回None。

要解决这个问题,核心是让拖拽的练习内容变成表单能识别的提交数据,最简单的办法是给每个盒子加一个隐藏的input,用它存储盒子里的练习,表单提交时就会把这些input的值传给后端。

修改后的HTML代码

<h2>Create Workout2</h2>

<script>
    function droppoint(event) {
        var data = event.dataTransfer.getData("Text");
        var nodeCopy = document.getElementById(data).cloneNode(true);
        nodeCopy.id = data + "-copy"; // 避免页面出现重复ID
        event.target.appendChild(nodeCopy);
        
        // 获取当前盒子对应的隐藏input,更新它的值
        const hiddenInput = event.target.querySelector('input[type="hidden"]');
        // 允许多个练习,用逗号分隔;如果只允许单个,直接赋值即可
        if (hiddenInput.value) {
            hiddenInput.value += "," + data;
        } else {
            hiddenInput.value = data;
        }
        
        event.preventDefault();
    }

    function allowDropOption(event) {
        event.preventDefault();
    }

    function dragpoint(event) {
        event.dataTransfer.setData("Text", event.target.id);
    }
</script>

<form action="/createworkout2" method="post">
    <div class="container text-center">
        <div class="row">
            <div class="col">
                <!-- 下拉菜单部分保持不变 -->
                <div class="dropdown">
                    <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                        Cardio
                    </button>
                    <ul class="dropdown-menu">
                        {% for cardio in cardio %}
                        <li><a class="dropdown-item" draggable="true" id="{{ cardio.exercise }}" ondragstart="dragpoint(event)">{{ cardio.exercise }}</a></li>
                        {% endfor %}
                    </ul>
                </div>
                <div class="dropdown">
                    <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                        Tone
                    </button>
                    <ul class="dropdown-menu">
                        {% for tone in tone %}
                        <li><a class="dropdown-item" draggable="true" id="{{ tone.exercise }}" ondragstart="dragpoint(event)">{{ tone.exercise }}</a></li>
                        {% endfor %}
                    </ul>
                </div>
                <div class="dropdown">
                    <button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                        Bulk
                    </button>
                    <ul class="dropdown-menu">
                        {% for bulk in bulk %}
                        <li><a class="dropdown-item" draggable="true" id="{{ bulk.exercise }}" ondragstart="dragpoint(event)">{{ bulk.exercise }}</a></li>
                        {% endfor %}
                    </ul>
                </div>
            </div>

            <div class="col">
                <div class="container">
                    <!-- 每个盒子添加隐藏input,name和盒子标识一致 -->
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        A
                        <input type="hidden" name="A" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        B
                        <input type="hidden" name="B" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        C
                        <input type="hidden" name="C" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        D
                        <input type="hidden" name="D" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        E
                        <input type="hidden" name="E" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        F
                        <input type="hidden" name="F" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        G
                        <input type="hidden" name="G" value="">
                    </div>
                    <div class="box" ondrop="droppoint(event)" ondragover="allowDropOption(event)">
                        H
                        <input type="hidden" name="H" value="">
                    </div>
                </div>
            </div>
        </div>
    </div>
    <button class="btn btn-primary" type="submit">Confirm</button>
</form>

修改后的Flask后端代码

如果盒子允许多个练习,需要把逗号分隔的字符串拆分成列表:

@app.route("/createworkout2", methods=["GET", "POST"])
@login_required
def createworkout2():
    """View and edit personal workouts"""
    cardio = db.execute("SELECT exercise FROM exercises WHERE type LIKE '%cardio%'")
    tone = db.execute("SELECT exercise FROM exercises WHERE type LIKE '%tone%'")
    bulk = db.execute("SELECT exercise FROM exercises WHERE type LIKE '%bulk%'")

    if request.method == "POST":
        # 获取盒子C的练习内容
        activity1 = request.form.get("C")
        if activity1:
            # 拆分多个练习为列表
            exercises_c = activity1.split(",")
            flash(f"Box C exercises: {', '.join(exercises_c)}")
        else:
            flash("Box C has no exercises")
        
        return redirect("/")
    else:
        return render_template("createworkout2.html", cardio=cardio, tone=tone, bulk=bulk)

额外说明

  • 克隆元素时修改了ID(data + "-copy"),避免页面出现重复ID的元素,符合HTML规范。
  • 如果每个盒子只允许一个练习,直接覆盖隐藏input的值即可,去掉逗号拼接的逻辑。
  • 移除了下拉菜单<ul>上冗余的draggable和ondragstart属性,这些只需要加在<a>标签上即可。

内容的提问来源于stack exchange,提问作者AndyM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 04:50:23