【问题标题】:How to select only date part in postgres by using django ORM如何使用 django ORM 在 postgres 中仅选择日期部分
【发布时间】:2017-05-10 14:20:08
【问题描述】:

我的后端设置如下

  • Postgres 9.5
  • Python 2.7
  • Django 1.9

我有一个日期时间类型的表,名为createdAt。我想使用 Django ORM 选择只有日期部分的字段,并按createdAt 分组。

例如,这个createdAt字段可能存储2016-12-10 00:00:00+02016-12-11 10:10:05+02016-12-11 17:10:05+0 ...等。

使用Djanggo ORM,输出应该是2016-12-102016-12-11。对应的sql应该类似于:SELECT date(createdAt) FROM TABLE GROUP BY createdAt

谢谢。

【问题讨论】:

  • 您是在尝试按日期使用分组函数(例如 count(*))还是仅以此为例?如果您只需要显示模板过滤器,或者如果经常使用它,则可以使用模板过滤器,也许可以创建一个模型属性。

标签: python django python-2.7 django-orm


【解决方案1】:

你可以试试:

  1. 使用__date 运算符按DateTimeField 过滤,日期部分为:createAt__date,这类似于__lt__gt
  2. 使用annotate/Func/F 创建一个基于createAt 的额外字段,仅显示日期部分。
  3. 使用valuesannotateCount/Sum创建group by查询。

示例代码

from django.db import models
from django.db.models import Func, F, Count

class Post(models.Model):
    name = models.CharField('name', max_length=255)
    createAt = models.DateTimeField('create at', auto_now=True)

Post.objects.filter(createAt__date='2016-12-26')    # filter the date time field for specify date part                         
            .annotate(createAtDate=Func(F('createAt'), function='date'))  # create an extra field, named createAtDate to hold the date part of the createAt field, this is similar to sql statement: date(createAt) 
            .values('createAtDate')  # group by createAtDate                                     
            .annotate(count=Count('id')) # aggregate function, like count(id) in sql statement

输出

[{'count': 2, 'createAtDate': datetime.date(2016, 12, 26)}]

注意:

  1. 为了指定每个方法的功能,我将长语句分成多个片段,因此在将回车粘贴到代码时需要删除它。
  2. 当您在应用程序中打开时区时,例如USE_TZ = True,在 django 中比较两个日期时需要更加小心。当您进行上述查询时,时区很重要。

希望它会有所帮助。 :)

【讨论】:

    【解决方案2】:

    Django 提供Manager.raw() 来对模型执行原始查询,但原始查询必须包含在您的情况下无用的主键。如果Manager.raw() 不够,您可能需要执行未完全映射到模型的查询,您始终可以直接访问数据库,使用connection 完全围绕模型层进行路由。 connection 对象代表默认的数据库连接。所以你可以像这样执行查询。

    from django.db import connection
    #acquire cursor object by calling connection.cursor()
    cursor = connection.cursor()
    cursor.execute('SELECT created_at from TABLE_NAME GROUP BY created_at')
    

    执行查询后,您可以遍历游标对象以获取查询结果。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-27
      • 1970-01-01
      • 2016-10-02
      • 1970-01-01
      • 2020-12-20
      • 2012-06-12
      相关资源
      最近更新 更多