I have two models ItemCategory and Item, I want to filter the list of ItemCategory by filtering is_published field of item.
class ItemCategory(models.Model):
category_name = models.CharField(max_length=50, unique=True)
category_image = models.ImageField(upload_to='item-category', null=True)
def __str__(self):
return 'category: ' + self.category_name
class Item(models.Model):
item_name = models.CharField(max_length=50)
item_desc = models.CharField(max_length=500, blank=True)
price = models.FloatField()
item_image = models.ImageField(upload_to='item-images')
num_of_items_available = models.IntegerField()
category_name = models.ForeignKey(ItemCategory, on_delete=models.CASCADE, null=True, related_name='items')
is_published = models.BooleanField(default=False)
def __str__(self):
return 'item: ' + self.item_name
Here is my approach but didn't get any success.
class ItemCategoryView(viewsets.ViewSet):
permission_classes = (AllowAny,)
serializer_class = ItemCategoryListSerializer
def list(self, request, format=None):
queryset = ItemCategory.objects.filter(items__in=Item.objects.filter(is_published=True))
serializer = ItemCategorySerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
ItemCategorySerializer looks like this
class ItemSerializer(serializers.ModelSerializer):
class Meta:
model = Item
fields = ('pk', 'item_name', 'item_desc', 'price', 'item_image', 'num_of_items_available',
'category_name', 'is_published')
class ItemCategorySerializer(serializers.ModelSerializer):
items = ItemSerializer(many=True, read_only=True)
class Meta:
model = ItemCategory
fields = ('pk', 'category_name', 'category_image', 'items')
Can anyone tell my how i can approach to this problem?
Edit
I have tried this two queries
queryset = ItemCategory.objects.filter(items__in=Item.objects.filter(is_published=True)) queryset = ItemCategory.objects.filter(items__is_published=True)
I think both this query work but not in the way i want. Heres how it works now.
It returns list of ItemCategory where any list of item with is_published = True. Say There are 3 categories(A, B , C) and each category has 3 list of item (A1, A2, A3, B1, B2, B3, C1, C2, C3). and let all have is_published = False except C3.
So now the query result is something like this. It returns only C Category with all the list item C1, C2, C3. which is not the desired result. I should be getting only C3 since this is the only published Item.
You can achieve this with filter
and prefetch_related
:
queryset = ItemCategory.objects.filter(items__is_published=True).prefetch_related(Prefetch("items", queryset=Item.objects.fiter(is_published=True))