首页 > 解决方案 > Django:获取 AVG 的查询集不起作用

问题描述

目前,我尝试获取数据库中特定问题的所有答案的平均值。为此,我编写了以下查询集。答案都是数字,但我的查询集似乎仍然存在问题。我收到以下错误消息 function avg(text) does not exist LINE 1: SELECT AVG("surveys_answer"."answer") AS "avg" FROM "surveys...

answers = Question.objects.filter(
    focus=QuestionFocus.AGE,
    survey__event=self.request.event,
    survey__template=settings.SURVEY_POST_EVENT,
).aggregate(avg=Avg('answers__answer'))

模型.py

class Question(TimeStampedModel):
    survey = models.ForeignKey([...])
    question_set = models.ForeignKey([...])
    title = models.CharField([...])
    help_text = models.TextField([...])
    type = models.CharField([...])
    focus = models.CharField([...])
    required = models.BooleanField([...])
    position = models.PositiveSmallIntegerField([...])

class Answer(TimeStampedModel):
    question = models.ForeignKey(related_name='answers')
    response = models.ForeignKey([...])
    answer = models.TextField([...])
    choices = models.ManyToManyField([...])

标签: pythondjango

解决方案


答案都是数字,但我的查询集似乎仍然存在问题。

这不是您的查询集的问题。这是您的模型和数据库的问题。如果您的值是数字的,则需要使用IntegerFieldDecimalFieldFloatField或其他以数字方式将数据存储在数据库中的东西。例如:

class Answer(TimeStampedModel):
    question = models.ForeignKey(related_name='answers')
    response = models.ForeignKey([...])
    answer = models.IntegerField([...])
    choices = models.ManyToManyField([...])

严格来说,你可以将其转换为数据库中的数值数据,但这很不安全,只会让建模问题持续存在:

from django.db.models import IntegerField
from django.db.models.functions import Cast

answers = Question.objects.filter(
    focus=QuestionFocus.AGE,
    survey__event=self.request.event,
    survey__template=settings.SURVEY_POST_EVENT,
).aggregate(avg=Avg(Cast('answers__answer', output_field=IntegerField())))

但是,防止在数据库中输入非数字数据比尝试通过查询来缓解问题要好得多。


推荐阅读