如何排除 prefetch_related 字段为空的行
How to exclude rows with empty prefetch_related field
我用 prefetch_related
和 Prefetch
:
prefetch_qs = Offer.objects.filter(price__gt=1000)
prefetch = Prefetch('offers', queryset=prefetch_qs)
如何排除商品为空的行?它不起作用,因为注释计算了所有报价(未在 prefetch
中过滤):
filtered_qs = Product.objects.annotate(
offers_count=Count('offers')
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
Prefetch
作为产品查询后的第二个查询执行,因此无法根据预取过滤掉产品。您需要将预取过滤重复为子查询或您尝试进行的计数。
为了使计数正常工作,请尝试以下操作:
filtered_qs = Product.objects.annotate(
offers_count=Count('offers', filter=Q(offers__price__gt=1000))
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
为了用子查询来完成它,你需要这样的东西:
filtered_qs = Product.objects.annotate(
offers_count=Subquery(
prefetch_qs.filter(product=OuterRef('pk'))
.values('product')
.annotate(count=Count('pk'))
.values('count')
)
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
子查询方法可能看起来有点难以理解为什么这样做,我试图在一些旧问题中解释它
补充@Todor 的回答:您可以创建自定义子查询类型来简化第二种方法并允许重用。
class SubqueryCount(Subquery):
template = '(SELECT COUNT(*) FROM (%(subquery)s) _sub)'
output_field = IntegerField()
filtered_qs = Product.objects.annotate(
offers_count=SubqueryCount(prefetch_qs.filter(product=OuterRef('pk'))
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
我用 prefetch_related
和 Prefetch
:
prefetch_qs = Offer.objects.filter(price__gt=1000)
prefetch = Prefetch('offers', queryset=prefetch_qs)
如何排除商品为空的行?它不起作用,因为注释计算了所有报价(未在 prefetch
中过滤):
filtered_qs = Product.objects.annotate(
offers_count=Count('offers')
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
Prefetch
作为产品查询后的第二个查询执行,因此无法根据预取过滤掉产品。您需要将预取过滤重复为子查询或您尝试进行的计数。
为了使计数正常工作,请尝试以下操作:
filtered_qs = Product.objects.annotate(
offers_count=Count('offers', filter=Q(offers__price__gt=1000))
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
为了用子查询来完成它,你需要这样的东西:
filtered_qs = Product.objects.annotate(
offers_count=Subquery(
prefetch_qs.filter(product=OuterRef('pk'))
.values('product')
.annotate(count=Count('pk'))
.values('count')
)
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)
子查询方法可能看起来有点难以理解为什么这样做,我试图在一些旧问题中解释它
补充@Todor 的回答:您可以创建自定义子查询类型来简化第二种方法并允许重用。
class SubqueryCount(Subquery):
template = '(SELECT COUNT(*) FROM (%(subquery)s) _sub)'
output_field = IntegerField()
filtered_qs = Product.objects.annotate(
offers_count=SubqueryCount(prefetch_qs.filter(product=OuterRef('pk'))
).filter(
offers_count__gt=0
).prefetch_related(
prefetch
)