I have an array of tags as a model field, I want to filter out based on those array elements. here is the model in which tag field is an array type I guess.
class Mineral(models.Model):
name=models.CharField(max_length=500)
tags=TaggableManager()
def __unicode__(self):
return self.name
Now in my view, I want to filter out based on this tag field I can do that using Django way like this
class MineralList(APIView):
queryset = Mineral.objects.all()
serializer_class = MineralSerializer
permission_classes = [AllowAny]
def get(self, request, format=None):
mineral = Mineral.objects.all()
tags = request.query_params.get('tags', None)
name= request.query_params.get('name',None)
if tags is not None:
tags = tags.split(',')
mineral = mineral.filter(tags__name__in=tags).distinct()
if name:
mineral = mineral.filter(name=name)
serializer = MineralSerializer(mineral, many=True)
return Response(serializer.data)
How can I do that in REST way using filter backends and Filter class
You could create the FilterSet class like this:
from django_filters.rest_framework import FilterSet, filters
from django_filters.widgets import CSVWidget
class MineralFilterSet(FilterSet):
tags = filters.CharFilter(distinct=True, widget=CSVWidget, method='filter_tags')
name = filters.CharFilter()
class Meta:
model = Mineral
fields = ['name', 'tags']
def filter_tags(self, queryset, name, value):
return queryset.filter(tags__name__in=value)
And your view should be like this:
from django_filters.rest_framework import DjangoFilterBackend
class MineralList(ListAPIView):
queryset = Mineral.objects.all()
serializer_class = MineralSerializer
permission_classes = [AllowAny]
filter_backends = (DjangoFilterBackend,)
filter_class = MineralFilterSet