[Solved]-Django REST Framework ManyToMany filter multiple values

16๐Ÿ‘

โœ…

You can chain filters. For example, if you need all users which labels contain both 1 and 2 values, you can write a query like so:

User.objects.filter(labels=1).filter(labels=2)

django-filters does not support queries like this by default so you need a custom filter.

class M2MFilter(django_filters.Filter):

    def filter(self, qs, value):
        if not value:
            return qs
    
        values = value.split(',')
        for v in values:
            qs = qs.filter(labels=v)
        return qs


class UserFilter(django_filters.FilterSet):
    labels = M2MFilter(name='labels')

    class Meta:
        model = User
        fields = ('labels',)

Now you can write labels idโ€™s comma-separated and get exactly what you need

/api/users/?labels=1,2

Here is good answer about m2m queries

๐Ÿ‘คIvan Semochkin

1๐Ÿ‘

I have the same question and I found something like this:

from django.db.models import Q
from rest_framework import viewsets

class YourViewSet(viewsets.ModelViewSet)

    def get_queryset(self):
        # get lable infos here
        lables_info = self.request.query_params.get('lable')
        lables = lables_info.split(',')
        lable1, lable2 = lables[0], lables[1]

        return models.objects.fliter(
            Q(lable=lable1) | Q(lable=lable2)
        )
.......

Django==2.2.4

djangorestframework==3.10.2

django-filter==2.2.0

๐Ÿ‘คDeron Lee

0๐Ÿ‘

Using linked filters in UserViewSet as follows:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    def get_queryset(self):
        queryset = User.objects.all()
        labels = eval(self.request.query_params.get('labels', []))
        for label in labels:
            queryset = queryset.filter(labels__in=[label])
        return queryset

and querying like:

/api/users/?labels=[1,2]

seems to work!

๐Ÿ‘คTheDimLebowski

Leave a comment