Django过滤器与外键错误:精确查询需通过切片限制单结果
问题解决:根据登录用户关联供应商过滤Enquiry
错误原因分析
你遇到的The QuerySet value for an exact lookup must be limited to one result using slicing错误,本质是用了整个供应商QuerySet做精确匹配:你把Supplier_Profile.objects.all()(所有供应商的集合)传给了filter(name__suppliers_consulted=...),而默认的精确匹配(=)只能接受单个对象,不能处理多对象集合。更关键的是你的逻辑偏离需求——你要的是当前登录用户所属供应商的Enquiry,不是所有供应商的。
完整解决方案
1. 修正视图逻辑(核心)
从登录用户出发,找到其绑定的供应商公司,再过滤出对应Enquiry:
from django.contrib.auth.decorators import login_required @login_required # 强制用户登录,未登录自动跳转到登录页 def list_supplier_response(request): # 尝试获取当前用户的供应商档案 try: # 通过OneToOneField的反向关联直接获取用户的供应商档案 supplier_user_profile = request.user.supplier_user_profile # 拿到用户所属的供应商公司 user_supplier = supplier_user_profile.supplier_company # 过滤:关联的RFQ的供应商列表包含当前用户的公司 enquiries = Enquiry.objects.filter(name__suppliers_consulted=user_supplier) except Supplier_User_Profile.DoesNotExist: # 若用户未绑定供应商档案,返回空列表 enquiries = Enquiry.objects.none() return render(request, 'main/list_supplier_response.html', {'enquiries': enquiries})
关键说明:
- 利用Django自动生成的OneToOneField反向关联
request.user.supplier_user_profile,直接定位用户的供应商档案 - 过滤时传入单个
user_supplier对象,避免了QuerySet匹配的错误
2. 修正模板代码
模板中无需调用.all(),直接遍历QuerySet即可,同时补充空数据提示:
{% for enquiry in enquiries %} <td><a class="btn btn-outline-primary" href="">{{ enquiry.name.rfq_name.name }}</a></td> {% empty %} <td>暂无分配的询价内容</td> {% endfor %}
优化点:
- 原
{{enquiry.name}}显示的是RFQ对象,建议改成{{ enquiry.name.rfq_name.name }}直接显示产品名称(需根据Product模型的实际字段名调整) - 增加
{% empty %}分支,处理无数据的场景
额外注意事项
- 确保
Supplier_User_Profile与User的OneToOneField没有自定义related_name,如果有,要把request.user.supplier_user_profile改成对应的名称 - 若后续需要支持一个用户属于多个供应商,可将过滤条件改为
name__suppliers_consulted__in=[user_supplier1, user_supplier2](需先获取用户的多供应商列表)
内容的提问来源于stack exchange,提问作者PhilM
相关产品推荐
相关产品推荐

