Как мне получить, чтобы мой запрос Django возвращал только среднее значение и другой столбец? - PullRequest
0 голосов
/ 10 апреля 2019

Я использую 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)

, но это приводит к ошибке «Ошибка типа: ожидаемая строка или байтовоподобный объект».Я запутался в том, как указать часть «GROUP BY» в моем операторе SQL, а затем запутался в том, как вернуть два столбца данных, которые мне нужны, поскольку я думаю, что приведенное выше возвращает только объекты ArticleStat, которые нетам нет моего среднего.

1 Ответ

0 голосов
/ 10 апреля 2019

Вам необходимо установить поле вывода для аннотации hour, в противном случае Django не будет знать, что вы преобразовали исходный тип даты (created_on) в числовой тип (hour), и ожидает его передачи.строка даты (или объект даты, который, однако, не смущает).Если вы передадите дату от hour до filter(), вы увидите, что 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()
    ))
)
...