You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中前两个视图正常,如何让过滤类视图生效?

解决Django过滤视图失效的问题

你的过滤功能失效主要有两个核心问题,逐一解决即可:

1. URL路由冲突

在urls.py中,你定义了两个完全相同的路径blogposts/:

  • 第一个是BlogPostListCreate视图
  • 第二个是BlogPostList过滤视图

Django的URL匹配是从上到下优先匹配第一个符合的路径,所以你的过滤视图永远不会被触发。

解决方法:

给过滤视图设置一个唯一的路径,比如blogposts/filter/,修改后的urls.py:

urlpatterns = [
    path("blogposts/", views.BlogPostListCreate.as_view(), name="Blogpost-view-create"),
    path("blogposts/<int:pk>/", views.BlogPostRetrieveUpdateDestroy.as_view(), name="update"),
    path("blogposts/filter/", views.BlogPostList.as_view(), name="Filter"),
]

或者更优的方案:把过滤逻辑合并到已有的BlogPostListCreate视图中,避免重复的路径和视图,具体见下文的优化方案。

2. ORM过滤语法错误

在BlogPostList的get方法中,你写的过滤条件是title_icontains,但Django ORM的字段查找需要使用双下划线(__),正确的写法是title__icontains。单下划线会被Django识别为字段名的一部分,导致找不到对应字段而报错。

修复后的代码:

class BlogPostList(APIView):
    def get(self, request, format=None):
        title = request.query_params.get("title", "")
        
        if title:
            # 修复双下划线
            blog_posts = BlogPost.objects.filter(title__icontains=title)
        else:
            blog_posts = BlogPost.objects.all()
        
        serializer = BlogPostSerializer(blog_posts, many=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

优化方案(推荐)

既然BlogPostListCreate已经是列表视图,完全可以把过滤逻辑整合进去,不用单独写一个APIView,更符合DRF的设计习惯:

修改BlogPostListCreate类,重写get_queryset方法:

class BlogPostListCreate(generics.ListCreateAPIView):
    queryset = BlogPost.objects.all()
    serializer_class = BlogPostSerializer

    def get_queryset(self):
        # 获取基础查询集
        queryset = super().get_queryset()
        # 从查询参数中获取title
        title = self.request.query_params.get("title", "")
        if title:
            # 添加过滤条件
            queryset = queryset.filter(title__icontains=title)
        return queryset

    def delete(self, request, *args, **kwargs):
        BlogPost.objects.all().delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

这样修改后,你可以直接访问原路径blogposts/?title=xxx来实现过滤,同时保留原有的创建、删除功能,还能删掉多余的BlogPostList视图和对应的URL路由,代码更简洁。

测试方法

不管用哪种方案,测试时直接在URL后添加查询参数即可,比如:

  • 单独路径方案:http://localhost:8000/blogposts/filter/?title=测试
  • 整合方案:http://localhost:8000/blogposts/?title=测试

内容的提问来源于stack exchange,提问作者Awm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 09:43:21