first of all I apologize if I did not ask a question using better words. I am building a DRF App, I have Products
Model, ProductSerializer
and ProductsSummaryView
. Furthermore, I have Workspace Model (not going to talk about it as it is not related to the issue). Now, I want to return those products details in success response which are attached with a specific Workspace, filtered on some parameters.
What I have done:
I defined filterset_fields
and filter_backends
. It works fine. For example, if I go to this URL {{domain}}/path/?country__title=Japan
, it filters the data for Japan and show me. But the problem is, I want to filter using multi-tag, such as let's say if I want to see details for Japan and Korea, so I want something like this {{domain}}/path/?country__title=Japan&country__title=Korea
, but it is not working and it just returns all the details. I even tried adding empty list format in the URL and tried this URL {{domain}}/path/?country__title[]=Japan&country__title[]=Korea
, but it still did not work.
Can anybody help me in this?
My Product
Model is:
class Product(BaseModel):
"""Product model to store all prices of a product and
related brand and countries it's available in"""
product = models.CharField(max_length=255)
country = models.ForeignKey(Country, null=True, on_delete=models.DO_NOTHING)
fzg_segment = models.ForeignKey(
FZGSegment, on_delete=models.DO_NOTHING, null=True, blank=True
)
My ProductSerializer
Serializer is:
class ProductSerializer(serializers.ModelSerializer):
"""Serializer for the part object"""
fzg_segment = FZGSegmentSerializer()
class Meta:
model = Product
fields = (
"id",
"product",
"fzg_segment",
)
read_only_fields = ("id",)
And my ProductsSummaryView
API is:
class ProductsSummaryView(mixins.ListModelMixin, viewsets.GenericViewSet):
"""Viewset to return data for products in a workspace"""
serializer_class = serializers.ProductSerializer
permission_classes = (permissions.IsWorkspaceAdminPermission,)
pagination_class = StandardSetPagination
filter_backends = [DjangoFilterBackend]
filterset_fields = [
"fzg_segment__title",
"country__title",
]
def get_queryset(self) -> models.Product:
"""Returns queryset of all the products of a workspace"""
workspace = self.kwargs["workspace"]
workspace = get_object_or_404(models.Workspace, pk=workspace)
return workspace.products.all()
Can anyone help me and let me know what do I need to do in order to achieve desired functionality?
UPDATE:
I have created filters.py
file as below:
# filters.py
import django_filters
from .models import Product
class ProductFilter(django_filters.FilterSet):
fzg_segment__title = django_filters.CharFilter(field_name="fzg_segment__title", lookup_expr='in')
country__title = django_filters.CharFilter(field_name="country__title", lookup_expr='in')
class Meta:
model = Product
fields = [
"fzg_segment__title",
"country__title",
]
and I have update my views.py
as below:
# views.py
class ProductsSummaryView(mixins.ListModelMixin, viewsets.GenericViewSet):
"""Viewset to return data for products in a workspace"""
serializer_class = serializers.ProductSerializer
permission_classes = (permissions.IsWorkspaceAdminPermission,)
pagination_class = StandardSetPagination
filter_backends = [DjangoFilterBackend]
filterset_class = filters.ProductFilter
def get_queryset(self) -> models.Product:
"""Returns queryset of all the products of a workspace"""
workspace = self.kwargs["workspace"]
workspace = get_object_or_404(models.Workspace, pk=workspace)
queryset = workspace.products.all()
queryset = self.filter_queryset(queryset)
return queryset
and I tried to use filters as following in the URL:
{{domain]]/path/?country__title=Japan&country__title=Korea
and
`{{domain]]/path/?country__title__in=Japan&country__title__in=Korea``
and
{{domain]]/path/?country__title__in=Japan,Korea
and
{{domain]]/path/?country__title[]=Japan&country__title[]=Korea
But all in vain, I am unable to use even single filter, leave the multiple one. What is wrong am I doing?
You need to use BaseInFilter, example:
from django_filters.filters import BaseInFilter
from django_filters import rest_framework as filters
class CharInFilter(BaseInFilter, filters.CharFilter):
pass
class ProductFilterSet(filters.FilterSet):
country = CharInFilter(field_name="country__title", lookup_expr='in')
class Meta:
model = Product
fields = ["country"]
The params url like:
/?country=Japan,Korea