通过login_info筛选获取File表多列时解决get()返回多对象报错问题
问题解决方法
核心错误原因
你用了get()方法查询,但该方法要求结果唯一,当数据库里匹配到多条记录时就会触发报错。你的场景里,当前登录的parent对应了2条ParentMystudent记录,所以get()直接报错;后续查询File时如果一个学生对应多个文件,同样会踩这个坑。
修正后的views.py代码
# 用filter获取当前parent关联的所有ParentMystudent记录,返回可迭代的查询集 mystudents = ParentMystudent.objects.filter(parent=request.session['login_info'].get('id')) # 提取所有关联的学生ID,用__in批量查询对应的File记录 student_ids = mystudents.values_list('mystudent_id', flat=True) query = File.objects.filter(studentid__in=student_ids) # 用预查询优化关联数据,避免循环里重复查数据库(解决N+1查询问题) from django.db.models import Prefetch query = query.prefetch_related(Prefetch('studentid', queryset=Student.objects.all())) # 无需手动循环赋值,预查询会自动关联Student数据 return render(request, 'file.html', {'query': query})
代码修改说明:
- 把
get()换成filter(),获取多条记录的查询集,避免单条限制报错 - 用
values_list()提取所有学生ID,通过__in批量查询File表,一次获取所有目标数据 - 使用
prefetch_related优化查询性能,减少数据库访问次数 - 去掉多余的
if query判断,查询集本身可迭代,空集也不会触发错误
修正后的file.html代码
{% for obj in query %} <tr> <td><a href="#" class="fw-bold"></a>{{ forloop.counter }}</td> <td>{{ obj.soano }}</td> <td>{{ obj.studentid.lrn }}</td> <td><a href="{{ obj.file.url }}" target="_blank">{{ obj.studentid.lastname }}</a></td> </tr> {% endfor %}
模板修改说明:
- 删掉多余的
{% if obj in query.all %}判断,循环本身就是遍历query的每个对象 - 把错误的
<span src="...">改成<a href="...">,target="_blank"是a标签属性,span不支持,同时src要换成href - 根据模型外键字段名,把
obj.student改成obj.studentid(对应File模型里关联Student的字段)
内容的提问来源于stack exchange,提问作者nana
相关产品推荐
相关产品推荐

