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

在Django REST Framework嵌套路由中使用FilterSet类

可以在嵌套路由中使用PostFilterSet类,实现方法如下

完全可以在/users/[id]/posts/这个嵌套路由中复用已有的PostFilterSet类来实现标签过滤,下面提供两种规范的实现方式:

方法一:利用DRF Action的过滤配置(推荐)

直接在@action装饰器中指定该接口专属的过滤后端和过滤集类,覆盖UserViewSet本身的过滤配置,让DRF自动处理过滤逻辑:

from django_filters.rest_framework import DjangoFilterBackend
from .models import User, Post
from .serializers import UserSerializer, PostSerializer
from .filters import PostFilterSet

class UserViewSet(viewsets.ReadOnlyModelViewSet):
    serializer_class = UserSerializer
    queryset = User.objects.all()
    filter_backends = [DjangoFilterBackend]
    filterset_class = UserFilterSet

    @action(
        methods=["get"], 
        detail=True,
        filter_backends=[DjangoFilterBackend],
        filterset_class=PostFilterSet
    )
    def posts(self, request, pk):
        # 获取当前用户实例
        user = self.get_object()
        # 获取该用户的所有帖子查询集(确保Post模型中User关联字段的related_name为'posts')
        queryset = user.posts.all()
        # 让DRF自动应用过滤规则
        queryset = self.filter_queryset(queryset)
        # 序列化返回结果
        serializer = PostSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

这种方式遵循DRF视图集设计规范,自动处理请求参数的校验和过滤,同时保留了扩展其他过滤后端的灵活性。

方法二:手动实例化PostFilterSet

如果需要更灵活的过滤流程控制,可以直接在action方法中手动实例化并应用PostFilterSet:

@action(methods=["get"], detail=True)
def posts(self, request, pk):
    user = self.get_object()
    queryset = user.posts.all()
    # 手动初始化过滤集,传入请求参数和基础查询集
    filterset = PostFilterSet(request.GET, queryset=queryset)
    # 校验参数有效性后获取过滤后的查询集
    if filterset.is_valid():
        queryset = filterset.qs
    serializer = PostSerializer(queryset, many=True, context={'request': request})
    return Response(serializer.data)

补充:支持多标签过滤

如果需要同时过滤多个标签(比如/users/1/posts/?tags=tag1&tags=tag2),可以将PostFilterSet中的tags字段改为ModelMultipleChoiceFilter:

class PostFilterSet(filters.FilterSet):
    tags = filters.ModelMultipleChoiceFilter(queryset=Tag.objects.all())

    class Meta:
        model = Post
        fields = ("tags",)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 08:10:28