首页 > 解决方案 > 如何让我的 Django 查询只返回平均值和另一列?

问题描述

我正在使用 Django 和 Python 3.7。我有这些模型...

class Article(models.Model):
    website = models.ForeignKey(Website, on_delete=models.CASCADE, related_name='articlesite')
    title = models.TextField(default='', null=False)
    path = models.TextField(default='', null=False)
    url = models.TextField(default='', null=False)
    created_on = models.DateTimeField(db_index=True, default=datetime.now)


class ArticleStat(models.Model):
    objects = ArticleStatManager()
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='articlestats')
    elapsed_time_in_seconds = models.IntegerField(default=0, null=False)
    hits = models.FloatField(default=0, null=False)

我想编写一个 Django 查询,它返回两列数据——一个 elapsed_time_in_seconds (来自上面的 ArticleStat 模型)和这个特定间隔的平均点击次数。混合中还有其他一些限制。我不知道该怎么做。我尝试了以下

qset = ArticleStat.objects.annotate(avg_score=Avg(F("hits")),
                                    hour=(Func(
                                            Func(
                                                F("article__created_on"), function='HOUR FROM'),
                                            function='EXTRACT'))).filter(
    article__website=website,
    hour=hour)

但这会导致错误“TypeError:预期的字符串或类似字节的对象”。我对如何指定我的 SQL 语句的“GROUP BY”部分感到困惑,然后我对如何返回我想要的两列数据感到困惑,因为我认为上面只返回 ArticleStat 对象,这不会t 包括我的平均水平。

标签: pythondjangopython-3.xaggregateaverage

解决方案


您需要在注释上设置一个输出字段,否则Djangohour不知道您已将原始日期类型created_onhour但是没有说)。如果你传递一个关于 的日期hourfilter()你会看到那个TypeError消失了(但你会ProgrammingError从数据库中得到一个)。

因此,假设您将小时提取为整数,如何使用IntegerField

from django.db.models import IntegerField

qset = ArticleStat.objects.annotate(
    avg_score=Avg(F("hits")),
    hour=(Func(
            Func(F("article__created_on"), function='HOUR FROM'),
            function='EXTRACT',
            output_field=IntegerField()
    ))
)

推荐阅读