Django ListView配置ordering后返回查询集无序警告如何解决
问题产生原因
Django ListView 类提供的 ordering 属性仅会自动应用到父类默认生成的查询集上。当你重写了 get_queryset 方法并返回自定义的过滤查询集时,父类的排序逻辑不会自动生效,因此会出现返回结果无序、触发未排序查询集警告的问题。
另外你现有代码的参数判断逻辑存在漏洞:self.kwargs.get('district') 没有获取到参数时返回的是 None,而非 False,district != False 的判断会将 None 判定为成立,进入错误的过滤分支。
解决办法
有两种常用的修复方案:
方案一:手动给自定义查询集添加排序
在你自定义过滤的查询集后追加排序逻辑,直接复用已定义的 ordering 配置即可,修改后的视图代码如下:
class PostListView(ListView): model = Post template_name = 'mainapp/post-list.html' ordering = ['-created_at'] paginate_by = 5 def get_queryset(self, *args, **kwargs): district = self.kwargs.get('district') catagory = self.kwargs.get('catagory') if district: posts = Post.objects.filter(Q(catagory=catagory)& Q(district=district)).order_by(*self.ordering) else: posts = Post.objects.filter(catagory=catagory).order_by(*self.ordering) return posts
方案二:先调用父类方法获取已排序的查询集再过滤
先通过 super() 调用父类的 get_queryset 方法,拿到已经应用了 ordering 排序规则的查询集,再在这个基础上做过滤操作,代码如下:
class PostListView(ListView): model = Post template_name = 'mainapp/post-list.html' ordering = ['-created_at'] paginate_by = 5 def get_queryset(self, *args, **kwargs): # 先获取父类生成的已排序查询集 queryset = super().get_queryset(*args, **kwargs) district = self.kwargs.get('district') catagory = self.kwargs.get('catagory') if district: queryset = queryset.filter(Q(catagory=catagory)& Q(district=district)) else: queryset = queryset.filter(catagory=catagory) return queryset
内容的提问来源于stack exchange,提问作者anoop george
相关产品推荐
相关产品推荐

