Django 通过过滤对象列表来过滤对象列表
我有两个模型ItemCategory和Item,我想通过过滤Item的is_published字段来过滤ItemCategory的列表Django 通过过滤对象列表来过滤对象列表,django,django-rest-framework,django-queryset,django-filters,Django,Django Rest Framework,Django Queryset,Django Filters,我有两个模型ItemCategory和Item,我想通过过滤Item的is_published字段来过滤ItemCategory的列表 class ItemCategory(models.Model): category_name = models.CharField(max_length=50, unique=True) category_image = models.ImageField(upload_to='item-category', null=True) d
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
这是我的方法,但没有取得任何成功
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看起来像这样
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')
有人能告诉我如何解决这个问题吗
编辑
我试过这两个问题
queryset=itemcegory.objects.filter(items\uu in=Item.objects.filter(is\u published=True))queryset=itemcegory.objects.filter(items\uu is\u published=True)
我认为这两个查询都可以,但不是我想要的方式。这就是它现在的工作原理
它返回ItemCategory列表,其中发布了的任何项目列表=True。假设有3个类别(A、B、C),每个类别有3个项目列表(A1、A2、A3、B1、B2、B3、C1、C2、C3)。并且让所有人都有是发布的=False,除了C3
现在查询结果是这样的。它只返回包含所有列表项C1、C2、C3的C类别。这不是期望的结果。我应该只得到C3,因为这是唯一发布的项目 我认为您需要在返回类别本身之前过滤这些项目
QuerySet
管理器
1<代码>型号.py
class ItemCategory(models.Model):
category_name = models.CharField(max_length=50, unique=True)
category_image = models.ImageField(upload_to='item-category', null=True)
def get_published_items(self):
"""
return all items contains with this single Category.
"""
return Item.objects.published().filter(category_name__pk=self.pk)
def __str__(self):
return 'category: ' + self.category_name
class ItemQuerySet(models.QuerySet):
def published(self):
return self.filter(is_published=True)
def unpublished(self):
return self.filter(is_published=False)
class Item(models.Model):
....
category_name = models.ForeignKey(
ItemCategory, on_delete=models.CASCADE,
null=True, related_name='items')
is_published = models.BooleanField(default=False)
objects = ItemQuerySet.as_manager()
def __str__(self):
return 'item: ' + self.item_name
2。views.py
class ItemCategoryView(viewsets.ViewSet):
permission_classes = (AllowAny,)
serializer_class = ItemCategoryListSerializer
def list(self, request, format=None):
# find all categories first
published_categories_by_items = [ c.category_name for c in Item.objects.published() ]
# then, filter the categories itself.
queryset = ItemCategory.objects.filter(pk__in=[ c.pk for c in published_categories_by_items]).distinct()
serializer = ItemCategorySerializer(queryset, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
您可以通过
过滤器
和预取相关
来实现这一点:
queryset = ItemCategory.objects.filter(items__is_published=True).prefetch_related(Prefetch("items", queryset=Item.objects.fiter(is_published=True))
尝试以下操作:
queryset=itemcegory.objects.filter(items\uu is\u published=True)
this return itemcegory with published items.no它没有。我试过了。。有任何错误或它可以工作但不返回你想要的吗?嘿@nevervoner它可以工作。谢谢你,非常欢迎!我把它贴出来作为答复。