在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
相关产品推荐
相关产品推荐

