在Django的WHERE子句中添加自定义SQL,而不使用.raw()

时间:2014-06-16 01:02:16

标签: python sql django orm

我有一个复杂的django ORM查询,我真的不必转换为原始SQL,因为它是一个非常重要的查询,我想要一致性,我使用了一些ORM功能生成查询,并经过全面测试。

我想在datetime字段的WHERE子句中添加一个过滤器。但是,我只想测试 date 部分,而不是时间。

这是我现有查询的简化版本:

MyTable.objects.filter(date_field__gte=datetime.now().date())

但在某些情况下,我已将date_field转换为datetime_field以获得更高的精确度。但是,在这种情况下,我仍然想要一个仅限日期的比较。类似的东西:

MyTable.objects.filter(datetime_field__datepartonly__gte=datetime.now().date())

在postgres,我选择的数据库,这很简单:

SELECT * FROM mytable WHERE DATE(datetime_field) >= ...

如何在不将整个查询转换为原始SQL的情况下在django中执行此操作?

  • 我尝试使用F(),但您只能指定字段名称,而不是自定义SQL。
  • 我尝试使用Q(),但同样的交易。
  • 我尝试过Django的SQL函数(Sum等),但只有少数,看起来它们只是为agreggate查询而设计的。 我尝试使用别名,但you can't use aliases in a WHERE clause, either in Django, or in SQL

如何在不将整个查询转换为原始SQL的情况下在django中执行此操作?

1 个答案:

答案 0 :(得分:2)

您可以使用datetime对象的yearmonthday字段,但在此处测试之后,似乎不允许使用其他__gte应用程序到现场。

这将有效:

now = datetime.now()
results = MyTable.objects.filter(datetime_field__year=now.year, datetime_field__month=now.month, datetime_field__day=now.day)

但不允许接受。

您始终可以创建从0:00开始的日期时间

now = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0)
results = MyTable.objects.filter(datetime_field__gte=now)