I have models.py
from mptt.models import MPTTModel, TreeForeignKey
class Category(MPTTModel):
name = models.CharField(max_length = 255, null = False, blank = False)
parent = TreeForeignKey('self', on_delete = models.CASCADE, blank = False, null = True, related_name = 'children')
# other fields
class Product(models.Model):
category = models.ForeignKey(Category, on_delete = models.SET_NULL, null = True, blank = True, related_name = 'products')
# other fields
views.py
class ProductAPIView(generics.GenericAPIView):
serializer_class = ProductSerializer
queryset = Product.objects.all()
filter_backends = [ DjangoFilterBackend ]
filterset_class = ProductFilter
def get(self, request):
products = self.filter_queryset(self.get_queryset())
serializer = self.serializer_class(products, many = True)
return Response(serializer.data)
class CategoryAPIView(generics.GenericAPIView):
serializer_class = CategorySerializer
queryset = Category.objects.root_nodes()
filters.py
from django_filters import FilterSet, CharFilter, NumberFilter
from .models import Product
class ProductFilter(FilterSet):
brand = CharFilter(field_name='brand__name', lookup_expr='iexact')
category = CharFilter(field_name='category__name', lookup_expr='iexact')
discount = NumberFilter(field_name='discount', lookup_expr='gte')
class Meta:
model = Product
fields = {}
My categories queryset response looks like this
{
"name" : "electronics"
"parent" : None,
"products" : []
"children" : [
"name" : "cameras"
"parent" : "electronics",
"products" : []
"children" : [
"name": "DSLR Cameras",
"parent" : "cameras",
"products": [ "name": "Cannon EOS 80D DSLR Camera" ]
]
]
}
When i send query param with category=dslr cameras
, i'm able to get the products associated with this category, but if i send a parent category name like category=electronics
or category=cameras
, I'd want to deep search the Category
model to show products if the children also have these products. How can i achieve this?
Try this out:
class ProductFilter(FilterSet):
brand = CharFilter(field_name='brand__name', lookup_expr='iexact')
category = CharFilter(method='filter_category_name')
discount = NumberFilter(field_name='discount', lookup_expr='gte')
class Meta:
model = Product
fields = {}
def filter_category_name(self, queryset, name, value):
return queryset.filter(category__in=Category.objects.filter(name__iexact=value).get_descendants(include_self=True))