通过复选框获取多个ID报错:Field 'id' expected a number but got []
问题描述
Field 'id' expected a number but got []
我尝试通过复选框从列表中获取多个ID,但触发了上述错误。
我的代码
sample.html
<button href="/sample/save">Save</button> {% for obj in queryset %} <tr> <td><input type="checkbox" name="sid" value="{{obj.id}}"></td> <td>{{ obj.sample_name }}</td> <td>{{ obj.sample_type}}</td> <td>{{ obj.number}}</td> </tr> {% endfor %}
views.py
def sample(request): if request.method == 'GET': queryset = SampleList.objects.all() return render(request, 'lab_management/sample.html', {'queryset': queryset}) def save_doc(request): sid = request.POST.getlist('sid') sample = SampleList.objects.filter(id=sid)[0:10] template = DocxTemplate("doc.docx") context = { 'headers' : ['Name', 'Type', 'Number'], 'doc': [], } for samp in sample: list = [samp.name, samp.type, samp.number] context['doc'].append(list) template.render(context) template.save('new_doc.docx')
问题原因及修复方案
核心问题
- 提交方式错误:页面中的按钮用了
href跳转,实际是发送GET请求,但视图save_doc依赖request.POST获取数据,导致无法正确拿到复选框值。 - 多ID查询语法错误:Django ORM中用
id=sid匹配列表是错误的,应该用id__in=sid来实现多值匹配;同时未处理用户未选中任何复选框时sid为空列表的情况,直接查询会触发类型错误。 - 字段名不匹配:视图中
samp.name、samp.type和模型实际字段(HTML中的sample_name、sample_type)不一致,会导致属性不存在错误。
修复步骤
1. 修正HTML表单提交逻辑
用<form>包裹复选框和按钮,指定POST方法并添加Django必填的CSRF令牌:
<form method="POST" action="/sample/save"> {% csrf_token %} <button type="submit">Save</button> {% for obj in queryset %} <tr> <td><input type="checkbox" name="sid" value="{{obj.id}}"></td> <td>{{ obj.sample_name }}</td> <td>{{ obj.sample_type}}</td> <td>{{ obj.number}}</td> </tr> {% endfor %} </form>
2. 修正视图逻辑
from django.http import HttpResponseBadRequest def save_doc(request): # 仅处理POST请求 if request.method != 'POST': return HttpResponseBadRequest("请求方式错误") sid = request.POST.getlist('sid') # 处理未选中任何复选框的情况 if not sid: queryset = SampleList.objects.all() return render(request, 'lab_management/sample.html', { 'queryset': queryset, 'error': '请至少选择一个样本' }) # 使用__in查询多个ID sample = SampleList.objects.filter(id__in=sid)[:10] template = DocxTemplate("doc.docx") context = { 'headers' : ['Name', 'Type', 'Number'], 'doc': [], } # 字段名和模型保持一致,避免用list作为变量名(覆盖Python内置类型) for samp in sample: item = [samp.sample_name, samp.sample_type, samp.number] context['doc'].append(item) template.render(context) template.save('new_doc.docx') # 处理完成后返回成功页面或重定向 return render(request, 'lab_management/success.html')
内容的提问来源于stack exchange,提问作者krisssz
相关产品推荐
相关产品推荐

