Django-filter报错AssertionError:切片后无法过滤查询集,求视图层解法
解决Django-filter切片后无法过滤的问题
你的问题出在先对QuerySet执行切片操作,再传入Django-filter进行过滤——Django不允许对已切片的QuerySet应用后续过滤,因为切片会触发QuerySet的求值,使其无法再被修改或过滤。
正确实现步骤:
- 先获取前75条数据的主键列表(仅生成子查询,不会立即求值全量数据)
- 基于这些主键构建新的可过滤QuerySet,保持排序规则
- 传入Django-filter完成过滤后再做分页处理
修改后的视图函数代码:
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage from .models import RunStats from .filters import RunStatsFilter def hist_view_render(request): # 获取按create_dttm倒序的前75条数据的主键 top_75_pks = RunStats.objects.order_by('-create_dttm')[:75].values_list('pk', flat=True) # 基于主键构建可被过滤的QuerySet,保留排序 base_queryset = RunStats.objects.filter(pk__in=top_75_pks).order_by('-create_dttm') # 应用Django-filter过滤规则 hist_filter = RunStatsFilter(request.GET, queryset=base_queryset) # 分页处理 paginator = Paginator(hist_filter.qs, 15) page = request.GET.get('page') try: response = paginator.page(page) except PageNotAnInteger: response = paginator.page(1) except EmptyPage: response = paginator.page(paginator.num_pages) context = {'response': response, 'filter': hist_filter} return render(request, 'runstat_hist.html', context)
方案说明:
values_list('pk', flat=True)配合切片生成的是子查询,不会立即加载全量数据,仅限定后续QuerySet的范围filter(pk__in=top_75_pks)返回的是未被切片的QuerySet,完全符合Django-filter的处理要求- 最终分页的是过滤后的前75条数据子集,满足你的业务需求
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

