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

通过复选框获取多个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')

问题原因及修复方案

核心问题

  1. 提交方式错误:页面中的按钮用了href跳转,实际是发送GET请求,但视图save_doc依赖request.POST获取数据,导致无法正确拿到复选框值。
  2. 多ID查询语法错误:Django ORM中用id=sid匹配列表是错误的,应该用id__in=sid来实现多值匹配;同时未处理用户未选中任何复选框时sid为空列表的情况,直接查询会触发类型错误。
  3. 字段名不匹配:视图中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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:01:00