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

Django REST Framework中如何通过多个Medium ID过滤Artwork数据

解决Django REST Framework中多对多字段的多值过滤问题

Hey there! I see you're trying to fetch Artwork data by multiple medium_id values in DRF, and couldn't find a clear solution for many-to-many fields—let me walk you through a couple of straightforward approaches that work perfectly with your model code.

方案一:使用django-filter(推荐,简洁高效)

This is the most common and clean way to handle multi-value filtering in DRF. Here's how to set it up:

  1. First, install the library:
pip install django-filter
  1. Add it to your INSTALLED_APPS and configure DRF to use its filter backend in settings.py:
INSTALLED_APPS = [
    # ... your existing apps
    'django_filters',
]

REST_FRAMEWORK = {
    'DEFAULT_FILTER_BACKENDS': [
        'django_filters.rest_framework.DjangoFilterBackend',
        # ... other backends you might be using
    ],
}
  1. Create a filter class for your Artwork model. This is where we define the multi-value filter for medium IDs:
from django_filters import rest_framework as filters
from .models import Artwork

class ArtworkFilter(filters.FilterSet):
    # Use BaseInFilter to accept multiple values via repeated query params
    medium_id = filters.BaseInFilter(field_name='mediums__id', lookup_expr='in')
    # Alternatively, use CommaSeparatedInFilter if you prefer comma-separated values:
    # medium_id = filters.CommaSeparatedInFilter(field_name='mediums__id', lookup_expr='in')

    class Meta:
        model = Artwork
        fields = ['medium_id']
  1. Attach this filter to your viewset:
from rest_framework import viewsets
from .models import Artwork
from .serializers import ArtworkSerializer  # Assume you have this serializer
from .filters import ArtworkFilter

class ArtworkViewSet(viewsets.ModelViewSet):
    queryset = Artwork.objects.all()
    serializer_class = ArtworkSerializer
    filterset_class = ArtworkFilter

Now you can filter by multiple medium IDs like this:

  • If using BaseInFilter: your-domain.com/artworks/?medium_id=1&medium_id=2
  • If using CommaSeparatedInFilter: your-domain.com/artworks/?medium_id=1,2

方案二:自定义过滤(无需第三方库)

If you don't want to add another dependency, you can override the get_queryset method in your viewset to handle the filtering manually:

from rest_framework import viewsets
from .models import Artwork
from .serializers import ArtworkSerializer

class ArtworkViewSet(viewsets.ModelViewSet):
    queryset = Artwork.objects.all()
    serializer_class = ArtworkSerializer

    def get_queryset(self):
        queryset = super().get_queryset()
        # Get all medium_id values from the query params
        medium_ids = self.request.query_params.getlist('medium_id')
        
        if medium_ids:
            # Filter artworks that are linked to any of the specified medium IDs
            queryset = queryset.filter(mediums__id__in=medium_ids).distinct()
            # Add .distinct() to avoid duplicate results (since many-to-many joins can create duplicates)
        
        return queryset

This works with the same URL format as the first approach: ?medium_id=1&medium_id=2.

Bonus: Filter artworks linked to ALL specified mediums

If you need artworks that are associated with every medium ID in your list (not just any), adjust the filtering logic like this:

def get_queryset(self):
    queryset = super().get_queryset()
    medium_ids = self.request.query_params.getlist('medium_id')
    
    if medium_ids:
        # Filter artworks that have all specified mediums
        for mid in medium_ids:
            queryset = queryset.filter(mediums__id=mid)
        queryset = queryset.distinct()
    
    return queryset

Or using Q objects for a more concise (but equivalent) approach:

from django.db.models import Q

def get_queryset(self):
    queryset = super().get_queryset()
    medium_ids = self.request.query_params.getlist('medium_id')
    
    if medium_ids:
        query = Q()
        for mid in medium_ids:
            query &= Q(mediums__id=mid)
        queryset = queryset.filter(query).distinct()
    
    return queryset

内容的提问来源于stack exchange,提问作者Kiran S youtube channel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 06:59:09