python - 有没有办法通过 Django ORM 查询修改日期时间对象?

标签 python django python-3.x django-models django-queryset

我们有一个 Django、Postgresql 数据库,其中包含以下对象:

object_date = models.DateTimeField()

作为一个字段。

我们需要每天按小时统计对象,所以需要去掉一些多余的时间数据,例如:分、秒、微秒。

我们可以在python中去掉多余的时间数据:

query = MyModel.objects.values('object_date')
data = [tweet['tweet_date'].replace(minute=0, second=0, microsecond=0) for tweet in query

这给我们留下了一个包含日期和时间的列表。

我的问题:是否有更好、更快、更简洁的方法在查询本身中执行此操作?

最佳答案

如果只是想获取没有时间数据的日期,可以使用extra声明计算字段:

query = MyModel.objects
    .extra(select={
        'object_date_group': 'CAST(object_date AS DATE)',
        'object_hour_group': 'EXTRACT(HOUR FROM object_date)'
    })
    .values('object_date_group', 'object_hour_group')

不过,您不会从中获益太多;数据库现在向您发送更多数据。

但是,有了这些额外的字段,您可以使用聚合来立即获得您正在寻找的计数,只需添加一行:

query = MyModel.objects
    .extra(select={
        'object_date_group': 'CAST(object_date AS DATE)',
        'object_hour_group': 'EXTRACT(HOUR FROM object_date)'
    })
    .values('object_date_group', 'object_hour_group')
    .annotate(count=Count('*'))

或者,您可以使用任何有效的 SQL 将我创建的两个字段合并为一个字段,例如,通过将其格式化为字符串。这样做的好处是,您可以使用 tuple 构造一个 Counter 以方便查询(使用 values_list()) .

这个查询肯定会比用 Python 进行计数更有效率。然而,对于可能不那么重要的后台工作。

一个缺点是此代码不可移植;一方面,它不适用于 SQLite,您可能仍在使用它进行测试。在这种情况下,您可能会省去麻烦并立即编写一个原始查询,这将同样不可移植但更具可读性。

更新

从 1.10 开始,可以使用 expressions 很好地执行此查询, 感谢添加 TruncHour .以下是解决方案的外观建议:

from collections import Counter
from django.db.models import Count
from django.db.models.functions import TruncHour

counts_by_group = Counter(dict(
    MyModel.objects
        .annotate(object_group=TruncHour('object_date'))
        .values_list('object_group')
        .annotate(count=Count('object_group'))
)) # query with counts_by_group[datetime.datetime(year, month, day, hour)]

它优雅、高效且便携。 :)

关于python - 有没有办法通过 Django ORM 查询修改日期时间对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38271457/

相关文章:

python - 如何使用 Pandas 改进我的具有可迭代最大值的新列的庞大代码?

django - 如何访问 Django 模板中的数组元素?

Python 3 : list. 文档中的append()

python - Pathlib Path.rename() 创建中间目录的方式?

python - 估计由一组点(Alpha 形状??)生成的图像区域

python - 'for' 循环中 i = i + 1 和 i += 1 有什么区别?

python - 关于多站点的一般想法

django - 禁止(未设置 CSRF cookie。):/paypal/| Django

python-3.x - Pytesseract 混淆了零 ('0' )和大写 O ('O' )

python - 在字典中访问 Pandas 面具