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

Vue.js为表格行生成带递增整数的name属性 提交后Django无法取值如何解决

问题原因

  • 只有原生表单元素(<input>、<select>、<textarea>等)的name和值才会被默认表单提交逻辑携带,你给<td>标签加name属性、以及用contenteditable的<div>都不会被表单识别为提交字段,所以后端收不到对应值。
  • 模板中循环的变量名大小写不匹配:你写的是v-for="(row, index) in Rows",但Vue实例data里定义的是小写的rows,会导致循环失效,表格行根本不会渲染。
  • Django默认开启CSRF校验,表单提交不带CSRF令牌也会导致数据接收异常。

解决方案

1. 修正基础错误

把v-for的Rows改为小写的rows,和data中定义的变量保持一致,同时在form标签内添加Django的CSRF令牌字段。

2. 补充表单元素承载需要提交的值

不需要编辑的固定值用type="hidden"的<input>存储,可编辑内容优先用<input>实现,若必须保留contenteditable的交互效果,可以加事件把div的内容同步到隐藏input中。

修改后的前端代码示例:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
    <form id="myform" method="post" action="/tag_course/">
        {% csrf_token %} <!-- Django POST请求必须携带的CSRF令牌 -->
        <table>
            <thead>
            ...
            </thead>
            <tbody>
            <tr v-for="(row, index) in rows" :key="`isbn-${index}`">
                <td>
                    {{ row.title }}
                    <!-- 隐藏input存储固定的title值,带动态name -->
                    <input type="hidden" :name="`title_${index}`" :value="row.title">
                </td>
                <td bgcolor="white">
                    <!-- 方案1:直接用input实现可编辑,最省事 -->
                    <input type="text" :name="`discipline_code_course_code_${index}`">
                    
                    <!-- 方案2:必须保留contenteditable div的话用这个,同步值到隐藏input
                    <div contenteditable @input="e => $refs[`code_${index}`].value = e.target.innerText"></div>
                    <input type="hidden" :ref="`code_${index}`" :name="`discipline_code_course_code_${index}`">
                    -->
                </td>          
            </tr>
            </tbody>
        </table>
        <!-- 额外提交总行数,方便后端判断遍历范围 -->
        <input type="hidden" name="total_rows" :value="rows.length">
        <select id="semester" name="semester">
            <option value="test">test</option>
        </select>
        <button type="submit">提交</button>
    </form>
</div>
<script>
  var book_rows = [{title:1, author:1, edition:1}, {title:2, author:2, edition:2}, {title:3, author:3, edition:3}]
    const app = new Vue({
            el: '#app',
            data:() => ({
                filter: '',
                rows: book_rows
            }),
});
</script>

3. 后端取值逻辑

拿到总行数之后循环遍历即可:

def check(request):
    if request.method == 'POST':
        total_rows = int(request.POST.get('total_rows', 0))
        semester = request.POST.get('semester')
        for i in range(total_rows):
            title = request.POST.get(f'title_{i}')
            course_code = request.POST.get(f'discipline_code_course_code_{i}')
            # 这里处理每行的业务逻辑
            print(title, course_code)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 04:03:04