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

无需新增端点实现Documents的.filter()与.all()功能咨询

无需新增端点实现关联字段过滤的Django ModelViewSet方案

不用新增端点就能搞定,给你两个简洁方案,都是基于现有ModelViewSet扩展:

方案一:用django-filter(推荐,功能全)

默认的filter_fields确实不支持关联字段,官方推荐用django-filter来处理复杂过滤:

  1. 先装包:
    pip install django-filter
    
  2. 在settings.py里配置:
    INSTALLED_APPS = [
        # 其他已有的app
        'django_filters',
    ]
    
    REST_FRAMEWORK = {
        'DEFAULT_FILTER_BACKENDS': [
            'django_filters.rest_framework.DjangoFilterBackend',
        ],
    }
    
  3. 定义过滤规则类:
    from django_filters import rest_framework as filters
    from .models import Document
    
    class DocumentFilter(filters.FilterSet):
        # 关联字段用`field_name`指定外键的链式访问
        customer_id = filters.NumberFilter(field_name='customer__id')
        customer_name = filters.CharFilter(field_name='customer__name', lookup_expr='icontains')
        product_id = filters.NumberFilter(field_name='product__id')
        product_sku = filters.CharFilter(field_name='product__sku', lookup_expr='exact')
    
        class Meta:
            model = Document
            fields = ['customer_id', 'customer_name', 'product_id', 'product_sku']
    
  4. 把过滤类绑定到ViewSet:
    from rest_framework import viewsets
    from .models import Document
    from .serializers import DocumentSerializer
    from .filters import DocumentFilter
    
    class DocumentViewSet(viewsets.ModelViewSet):
        queryset = Document.objects.all()
        serializer_class = DocumentSerializer
        filter_class = DocumentFilter
    
  5. 使用方式:
    • 查全量文档:直接访问/api/documents/
    • 按客户ID过滤:/api/documents/?customer_id=1
    • 按产品SKU过滤:/api/documents/?product_sku=PROD001
    • 同时过滤客户和产品:/api/documents/?customer_id=1&product_id=2

方案二:自定义get_queryset(无需额外装包)

如果不想引入新依赖,直接重写ViewSet的get_queryset方法手动处理参数:

from rest_framework import viewsets
from .models import Document
from .serializers import DocumentSerializer

class DocumentViewSet(viewsets.ModelViewSet):
    queryset = Document.objects.all()
    serializer_class = DocumentSerializer

    def get_queryset(self):
        qs = super().get_queryset()
        # 从请求参数里拿过滤条件
        customer_id = self.request.query_params.get('customer_id')
        product_id = self.request.query_params.get('product_id')
        customer_name = self.request.query_params.get('customer_name')

        if customer_id:
            qs = qs.filter(customer__id=customer_id)
        if product_id:
            qs = qs.filter(product__id=product_id)
        if customer_name:
            qs = qs.filter(customer__name__icontains=customer_name)
        
        return qs

这种方式代码量稍大,但不需要额外依赖,适合简单过滤场景。

两种方案都能在同一个端点实现全量查询和关联过滤,完全不用新增端点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:05:10