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
相关产品推荐
相关产品推荐

