如何编写Django查询并在WHERE子句中包含PostGres函数(current_time)?

时间:2019-03-25 17:09:53

标签: python django python-3.x postgresql func

我正在使用Django,Python 3.7和PostGres 9.5。我想在Django中编写以下WHERE子句...

WHERE date_part('hour', current_time) = s.hour ...

因此,在阅读其他一些文档时,我被认为需要在运行查询之前编写一个“ Func”创建注释...

qset = ArticleStat.objects.annotate(
    hour_of_day=Func(
        'current_time',
        Value('hour'),
        function='date_part',
    )
).filter(hour_of_day=F("article__website__stats_per_hour__hour"))

但是,这会导致

Cannot resolve keyword 'current_time' into field. Choices are: article, article_id, elapsed_time_in_seconds, id, score

错误。似乎Django正在尝试将“ current_time”视为表中的一列,但我确实希望将其视为PostGres函数。我该怎么办?

1 个答案:

答案 0 :(得分:0)

更新2:阅读使用带注释的hour_of_day的filter子句,只需将子句转过来,一切都会变得很容易,除非我忽略了某些东西:

hour = datetime.datetime.now().hour
qset = ArticleStat.objects.filter(article__website__stats_per_hour__hour=hour)

更新:比下面的双重注释技巧更容易的是获取Python中的当前时间(每个查询一次,而不是每行一次)并将其传递给函数。您可能需要确保时区匹配。

import datetime
from django.db.models import DateTimeField
from django.db.models.expressions import Func, Value

current_time = datetime.datetime.now()
qset = Session.objects.annotate(
    hour_of_day=Func(
        Value('hour'),
        Value(current_time, output_field=DateTimeField()),
        function='date_part',
    )
)

一个简单的技巧就是使用两个注释,以避免将一个数据库函数嵌套在另一个注释中(如果您对此非常认真的话,可以使用Func的子类的自定义函数来做到):

from django.db.models import DateTimeField
from django.db.models.expressions import Func, Value

qset = MyModel.objects.annotate(
    current_time=Func(
        Value(0),
        function='current_time',
        output_field=DateTimeField()
    )).annotate(
    hour_of_day=Func(
        Value('hour'),
        F('current_time'),
        function='date_part',
    )
)