I have a model that I want to filter on multiple values.
my model:
class Product(models.Model):
ean = models.CharField(max_length=13, unique=True)
product_id = models.CharField(max_length=20, null=True, blank=True)
product_image = models.URLField(max_length=300, null=True, blank=True)
product_title = models.CharField(max_length=300, null=True, blank=True)
I either want to filter on the 'ean' field, or on the primary key, both will work. With my current set up, I only see the last value. For example, when I construct the URL as www.example.com/api/Product/?id=1&id=2, I only get see the product with id 2, and I want to see product with id 1 and with id 2.
How should I construct my ViewSet? Currently I have:
class ProductViewSet(ModelViewSet):
queryset = models.Product.objects.all()
serializer_class = serializers.ProductSerializer
filter_backends = [DjangoFilterBackend]
filter_fields = ('id','ean')
There is an even simpler way to achieve this using the django-filter
package. Deep within the django-filter
documentation, it mentions that you can use "a dictionary of field names mapped to a list of lookups".
Your code would be updated like so:
# views.py
from django_filters.rest_framework import DjangoFilterBackend
class ProductViewSet(ModelViewSet):
queryset = models.Product.objects.all()
serializer_class = serializers.ProductSerializer
filter_backends = [DjangoFilterBackend]
filterset_fields = {
'id': ["in", "exact"], # note the 'in' field
'ean': ["exact"]
}
Now in the URL you would add __in
to the filter before supplying your list of parameters and it would work as you expect:
www.example.com/api/Product/?id__in=1,2
The django-filter
documentation on what lookup filters are available is quite poor, but the in
lookup filter is mentioned in the Django documentation itself.