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

使用DRF实现多对多关系场景下通过查询参数过滤API数据

Django DRF 按作者名筛选书籍功能实现方案

以下两种实现方式可按需选择:

方案一:直接重写 get_queryset 方法(无需额外依赖)

适合过滤逻辑简单、不想引入额外第三方包的场景,核心是通过 request.query_params.getlist() 读取多个同名参数,再通过多对多关联字段过滤:

from rest_framework import viewsets
from .models import Book
from .serializers import BookSerializer

class BookViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        # 读取所有传入的author参数,返回列表
        author_names = self.request.query_params.getlist('author')
        if author_names:
            # 若前端传参带单引号(如示例?author='xxx'),可加这行清理引号
            cleaned_names = [name.strip("'") for name in author_names]
            # 多对多反向关联过滤:匹配任意一个作者名的书籍,distinct用于去重
            queryset = queryset.filter(authors__name__in=cleaned_names).distinct()
        return queryset

方案二:使用 django-filter 库(更规范,适合复杂过滤场景)

如果项目后续有更多过滤需求,推荐用专门的过滤库实现,维护性更强:

步骤1:安装并配置依赖

首先安装包:
pip install django-filter
然后在 settings.py 中注册应用:

INSTALLED_APPS = [
    # ... 其他应用
    'django_filters',
]

# 全局配置DRF默认过滤后端(也可以单独在View里配置)
REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
    ],
}

步骤2:自定义过滤器集

import django_filters
from .models import Book

class BookFilter(django_filters.FilterSet):
    # 指定author参数对应关联字段,AllValuesMultipleFilter自动支持多值传入
    author = django_filters.AllValuesMultipleFilter(field_name='authors__name', lookup_expr='exact')
    
    class Meta:
        model = Book
        fields = ['author']

步骤3:View中绑定过滤器

class BookViewSet(viewsets.ReadOnlyModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filterset_class = BookFilter # django-filter 2.x版本后用filterset_class代替旧版filter_class

注意事项

  • 上述两种方案默认逻辑是:只要书籍关联的作者存在任意一个匹配传入的作者名,就返回该书籍。如果你的需求是书籍必须同时匹配所有传入的作者,则需要把过滤逻辑改为循环叠加过滤条件:
    for name in cleaned_names:
        queryset = queryset.filter(authors__name=name)
    
  • 建议前端传参时省略单引号,直接使用 ?author=something1&author=something2 的格式,更符合HTTP参数规范,避免多余的字符串清理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 13:15:08