Django:基于注释进行注释

Posted

技术标签:

【中文标题】Django:基于注释进行注释【英文标题】:Django: Annotate based on an annotation 【发布时间】:2013-11-05 02:45:27 【问题描述】:

假设我正在使用 Django 管理有关运动员的数据库:

class Player(models.Model):
    name = models.CharField()
    weight = models.DecimalField()
    team = models.ForeignKey('Team')

class Team(models.Model):
    name = models.CharField()
    sport = models.ForeignKey('Sport')

class Sport(models.Model):
    name = models.CharField()

假设我想计算每支球队球员的平均体重。我想我会这样做:

Team.objects.annotate(avg_weight=Avg(player__weight))

但是现在说我想计算每项运动中团队权重的方差。有没有办法使用 Django ORM 做到这一点?在 QuerySet 上使用 extra() 方法怎么样?非常感谢任何建议。

【问题讨论】:

你能给我们举一个你想做的计算的例子吗?我假设您的意思是 avg_weight - specific_player.weight。 您不能在额外调用中引用由 annotate 调用创建的字段。但是,您可以尝试这样的事情:***.com/a/9284364/1637351 原始帖子(差异)中的具体示例是我想到的。但只是为了多样化,我可能还想知道,对于每项运动,该运动中每支球队的最大平均体重是多少。这有意义吗? 【参考方案1】:

你可以像这样使用查询:

class SumSubquery(Subquery):
    template = "(SELECT SUM(`%(field)s`) From (%(subquery)s _sum))"
    output_field = models.Floatfield()
    def as_sql(self, compiler, connection, template=None, **extra_context):
        connection.ops.check_expression_support(self)
        template_params = **self.extra, **extra_context
        template_params['subquery'], sql_params = self.queryset.query.get_compiler(connection=connection).as_sql()
        template_params["field"] = list(self.queryset.query.annontation_select_mask)[0]
        sql = template % template_params
        return sql, sql_params



Team.objects.all().values("sport__name").annotate(variance=SumSubquery(Player.objects.filter(team__sport_id=OuterRef("sport_id")).annotate(sum_pow=ExpressionWrapper((Avg("team__players__weight") - F("weight"))**2,output_field=models.Floatfield())).values("sum_pow"))/(Count("players", output_field=models.FloatField())-1))

并将相关名称添加到模型中,如下所示:

class Player(models.Model):
    name = models.CharField()
    weight = models.DecimalField()
    team = models.ForeignKey('Team', related_name="players")

【讨论】:

以上是关于Django:基于注释进行注释的主要内容,如果未能解决你的问题,请参考以下文章

django 使用基于查询的聚合值注释模型

Django 多注解返回错误结果

Django 使用转换变量进行注释

对中间模型 django 的一个字段进行注释

如何在 Django 中过滤对象以进行计数注释?

Django Rest Framework - 自动注释查询集