Django 注释子查询的聚合
Django annotate subquery's aggregation
所以我有三个模型
class Advert(BaseModel):
company = models.ForeignKey(Company, on_delete=CASCADE, related_name="adverts")
class Company(BaseModel):
name = models.CharField(max_length=50)
class OrderRating(BaseModel):
reported_company = models.ForeignKey(Company, on_delete=CASCADE, related_name='ratings')
rating = models.DecimalField(
max_digits=2,
decimal_places=1,
validators=[MinValueValidator(1.0), MaxValueValidator(5.0)],
help_text='Rating from 1.0 to 5.0.'
)
我正在尝试获取与公司相关的所有订单评级的平均值,并将其注释到 Advert
模型,当我这样做时:
qs = Advert.objects.all().annotate(
avg_rating=Subquery(
OrderRating.objects.filter(
reported_company=OuterRef('company')).aggregate(Avg("rating"))["rating__avg"]
)
)
我回来说
This queryset contains a reference to an outer query and may only be used in a subquery.'
当我在 Subquery
中调用 OuterRef
时不确定问题出在哪里。
根据我的经验 Subqueries
通常有点棘手而且没有很好的记录。当您的代码定义子查询时出现错误时,他们倾向于 return 您收到的消息(确实不是很有帮助的消息)。
据我所知 aggregate
在 Subequeries
中不起作用,您必须改用 annotations
。所以这应该有效:
qs = Advert.objects.all().annotate(
avg_rating=Subquery(
OrderRating.objects.filter(
reported_company=OuterRef('company')).values('reported_company').annotate(av=Avg('rating')).values('av')
)
)
所以我有三个模型
class Advert(BaseModel):
company = models.ForeignKey(Company, on_delete=CASCADE, related_name="adverts")
class Company(BaseModel):
name = models.CharField(max_length=50)
class OrderRating(BaseModel):
reported_company = models.ForeignKey(Company, on_delete=CASCADE, related_name='ratings')
rating = models.DecimalField(
max_digits=2,
decimal_places=1,
validators=[MinValueValidator(1.0), MaxValueValidator(5.0)],
help_text='Rating from 1.0 to 5.0.'
)
我正在尝试获取与公司相关的所有订单评级的平均值,并将其注释到 Advert
模型,当我这样做时:
qs = Advert.objects.all().annotate(
avg_rating=Subquery(
OrderRating.objects.filter(
reported_company=OuterRef('company')).aggregate(Avg("rating"))["rating__avg"]
)
)
我回来说
This queryset contains a reference to an outer query and may only be used in a subquery.'
当我在 Subquery
中调用 OuterRef
时不确定问题出在哪里。
根据我的经验 Subqueries
通常有点棘手而且没有很好的记录。当您的代码定义子查询时出现错误时,他们倾向于 return 您收到的消息(确实不是很有帮助的消息)。
据我所知 aggregate
在 Subequeries
中不起作用,您必须改用 annotations
。所以这应该有效:
qs = Advert.objects.all().annotate(
avg_rating=Subquery(
OrderRating.objects.filter(
reported_company=OuterRef('company')).values('reported_company').annotate(av=Avg('rating')).values('av')
)
)