我有以下型号:
class Assignment(models.Model):
extra_days = models.IntegerField(default=0)
due_date = models.DateTimeField()
Run Code Online (Sandbox Code Playgroud)
due_date分配到期的日期在何处,是在extra_days完成分配的截止日期之后给出的额外天数.
我想创建一个查询,返回due_date + extra_days大于当前日期的所有行.这就是我在做的事情:
from django.utils import timezone
from django.db.models import F
from datetime import datetime
cur_date = timezone.make_aware(datetime.now(), timezone.get_default_timezone())
a = Assignment.objects.filter(extra_days__gt=cur_date - F('due_date'))
Run Code Online (Sandbox Code Playgroud)
当我打印时a,我收到以下错误:
File "c:\Python27\lib\site-packages\MySQLdb\cursors.py", line 204, in execute
if not self._defer_warnings: self._warning_check()
File "c:\Python27\lib\site-packages\MySQLdb\cursors.py", line 117, in _warning
_check
warn(w[-1], self.Warning, 3)
Warning: Truncated incorrect DOUBLE value: '2013-09-01 02:54:31'
Run Code Online (Sandbox Code Playgroud)
如果我做了导致3.1天的时差,我假设天差仍然是3.我认为做这样的事情会更正确:
a = Assignment.objects.filter(due_date__gt=cur_date - timedelta(days=F('extra_days')))
Run Code Online (Sandbox Code Playgroud)
但这也会导致错误.
如何在不编写原始SQL查询的情况下执行此操作?
这取决于您使用的数据库后端,似乎是 PostgreSQL。
PostgreSQL 可以直接减去日期,所以下面的代码可以工作:
from django.db.models import F, Func
from django.db.models.functions import Now
class DaysInterval(Func):
function = 'make_interval'
template = '%(function)s(days:=%(expressions)s)'
qs = Assignment.objects.annotate(remaining_days=F('due_date') - Now())
qs.filter(remaining_days__lt=DaysInterval(F('extra_days')))
Run Code Online (Sandbox Code Playgroud)
这会产生以下 SQL:
SELECT "assignments_assignment"."id",
"assignments_assignment"."extra_days",
"assignments_assignment"."due_date",
("assignments_assignment"."due_date" - STATEMENT_TIMESTAMP()) AS "remaining_days"
FROM "assignments_assignment"
WHERE ("assignments_assignment"."due_date" - STATEMENT_TIMESTAMP())
< (make_interval(DAYS:="assignments_assignment"."extra_days"))
Run Code Online (Sandbox Code Playgroud)
对于其他数据库后端中的日期差异计算,请参阅DatediffMichael Brooks 创建的函数。
似乎我正在尝试做的事情是不可能的.我最后写了一个原始查询:
cursor.execute("SELECT * FROM app_assignment WHERE DATE_ADD(due_date, INTERVAL extra_days DAYS) > utc_timestamp()")
Run Code Online (Sandbox Code Playgroud)
我因为无法使用ORM来做一些看起来很简单而我考虑尝试SQLAlchemy的东西而感到震惊,但原始查询工作得很好.我总是尝试使用变通方法以确保我可以使用ORM,但我会使用原始SQL进行复杂查询.
| 归档时间: |
|
| 查看次数: |
4911 次 |
| 最近记录: |