【问题标题】:Django annotate subquery's aggregationDjango注释子查询的聚合
【发布时间】:2020-05-23 15:32:50
【问题描述】:

所以我有三个模型

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 时,不确定问题出在哪里。

【问题讨论】:

    标签: django django-orm django-aggregation django-annotate


    【解决方案1】:

    根据我的经验,Subqueries 通常有点棘手并且没有很好的文档记录。当定义子查询的代码中出现错误时,它们往往会返回您收到的消息(确实不是很有帮助的消息)。

    据我所知aggregateSubequeries 中不起作用,您必须改用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')
                )
            )
    

    【讨论】:

    • 这很遗憾总是返回一个空的查询集
    • 你是说qs还是avg_rating是空的?
    • 实际上刚刚开始工作,谢谢!这个问题非常有趣,在OrderRating meta 我也有ordering = ['created_at'],它不仅将sql查询翻译成ORDER BY reported_company,而且翻译成ORDER BY reported_company, created_at,这搞砸了一切,删除了固定的排序,现在给出了正确的输出.
    • 太好了,你解决了。虽然...这篇文章中的查询没有使用任何order_by?
    • 是的,我在模型的元数据中有一个默认排序,无论如何,如果您有兴趣阅读它,这就是问题所在:docs.djangoproject.com/en/3.0/topics/db/aggregation/…
    猜你喜欢
    • 2017-07-21
    • 2019-08-03
    • 1970-01-01
    • 2020-11-26
    • 2023-03-29
    • 2016-11-18
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    相关资源
    最近更新 更多