Django generic.ListView如何过滤掉没有关联Choice的Question
解决方案
1. 重写get_queryset的正确实现
直接借助Django ORM的反向关联能力在数据库层面完成过滤,代码如下:
class QuestionList(generic.ListView): model = Question template_name = 'polls/index.html' context_object_name = 'latest_question_list' def get_queryset(self): # choice__isnull=False 表示仅保留存在关联Choice的问题 # distinct() 用于去重,避免一对多关联导致同个Question出现多条重复记录 return Question.objects.filter(choice__isnull=False).distinct()
如果你的Choice模型中question外键字段自定义了related_name参数,将filter中的choice__isnull替换为{你定义的related_name}__isnull即可。如果需要保持原有排序逻辑,还可以在链式调用后追加.order_by()规则。
2. 两种过滤方案对比
- 优先选择上述ORM层面过滤的方案:过滤逻辑直接在数据库层执行,不需要把无关联Choice的无效数据加载到Django进程内存中,查询效率高,尤其数据量较大时性能优势非常明显,代码也更简洁易维护。
- 不推荐先查询所有Question再手动过滤:会额外查询不需要的数据,浪费数据库IO和内存资源,数据量稍大就会出现性能问题,无必要性。
内容的提问来源于stack exchange,提问作者Pavel Shikhov
相关产品推荐
相关产品推荐

