Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python datetime对象上的Django F表达式_Python_Django_Python 2.7_Django Queryset - Fatal编程技术网

Python datetime对象上的Django F表达式

Python datetime对象上的Django F表达式,python,django,python-2.7,django-queryset,Python,Django,Python 2.7,Django Queryset,我的模型是: class Test(): date1 = models.DateTimeField() date2 = models.DateTimeField() 我可以使用以下查询查找其date2大于date1的对象: Test.obejcts.filter(date2__gt=F('date1')) 我想查找date2大于date1一年的所有对象。 如何根据date1和date2之间的差异找出对象?一般解决方案: 您可以注释日期差异,然后对照时间增量(天数=365)(非常接

我的模型是:

class Test():
   date1 = models.DateTimeField()
   date2 = models.DateTimeField()
我可以使用以下查询查找其
date2
大于
date1
的对象:

Test.obejcts.filter(date2__gt=F('date1'))
我想查找
date2
大于
date1
一年的所有对象。

如何根据
date1
date2
之间的差异找出对象?

一般解决方案:

您可以
注释
日期差异,然后对照
时间增量(天数=365)
(非常接近@Anonymous在其评论中的建议):


PostgreSQL特定解决方案:

如果您使用的是
PostgreSQL
,则有另一个选项来自:

您可以一起使用和:


从django.db.models导入日期字段,ExpressionWrapper,F
从django.db.models.functions导入TruncDate
Test.obejcts.filter(
date2\uuu date\uuu gt=ExpressionWrapper(
TruncDate(F('date1'))+datetime.timedelta(天=365),
输出字段=日期字段(),
),
)
如果您真正需要的是类似于
date1=2019-05-14
date2>2020-05-14
。那么这种方法并不总是正确的,因为闰年有366天。这个问题可以通过同时使用
Trunc
Extract
函数来解决。不同的方法是可能的。。。例如:

来自django.db.models导入日期字段,ExpressionWrapper,F
从django.db.models.functions导入TruncDate、ExtractDay
日期\字段=日期字段()
年份=时间增量(天数=365)
闰年=时间增量(天数=366)
shifted_date1=ExpressionWrapper(
TruncDate(F(“日期1”)+年份,
输出字段=日期字段,
)
leap\u shift\u date1=ExpressionWrapper(
TruncDate(日期1)+闰年,
输出字段=日期字段,
)
qs=Test.objects.filter(
(
#如果。。。
Q(日期2\uu日期\uu gt=shift\u日期1)
&
(
#如果365天后的月份日期相同。。。
Q(日期1天=提取日(移位日期1))
|
#或者是2月29日
Q(
日期1__月=2,
date1_uuuDay=29,
)
)
)
|
Q(
#其他情况下使用366天
日期2\uuuu日期\uuuu gt=leap\u shift\u日期1,
)
)
注意:如果您有
功能,请使用_TZ=True
并在特定时区执行查询(例如使用
时区。在之前激活(…)
) 执行查询集),那么在添加
timedelta
之前执行
TruncDate
很重要,因为在每年不同日期执行切换到“夏令时”的国家,执行
TruncDate(F('date1')+timedelta(…)
可能会给出错误的结果。例如:

  • 一些国家在2019年切换到DST时间
    2019-03-31
    ,并将在2020年切换到
    2020-03-29
  • 当地时间2019-03-30 23:30尚未使用DST
  • 加上366天(因为明年是闰年)将给出
    2020-03-30 23:30“非DST”
    ,因此在“正常化”之后,这个日期时间将变为
    2020-03-31 00:30“DST”
  • 在添加timedelta之前使用
    TruncDate
    可以解决问题,因为
额外信息:一些国家/地区在固定日期切换到DST,例如每年2月1日,其他国家/地区可能在“3月最后一个星期日”切换,这可能是每年不同的日期

导入pytz 导入日期时间 基辅本地化(datetime.datetime(2011,3,28,0,1))-基辅本地化(datetime.datetime(2010,3,28,0,1)) #'datetime.timedelta(36482800)`小于365天 p.p.S.“闰秒年”(
2016-12-31 23:59:60.999
)的最后几秒也可能受到TruncDate/timedelta shift排序的影响,但“幸运的是”大多数数据库不支持闰秒,而python的
datetime.datetime

也缺少此功能

没有现成的安装工具可供尝试,但是
Test.objects.annotate(下一年=F('date1')+timedelta(days=365)).filter(下一年=F('date2'))呢
?或者在注释表达式中减去两个日期。如果我使用Test.objects.annotate(duration=F('date2')-F('date1')),我会在queryset中得到一些十进制值。这些值是什么?@mahabuburrahamanmellow您是否有可能使用MySQL?是的,我正在使用MySQL。这是此解决方案的问题吗?尝试使用
annotate(duration=F('end\u time')-F('start\u time'))。filter(duration\u gt=timedelta(0299))
但我收到了一个错误:
TypeError:expected string或bytes-like-object
@sytech似乎是代码其他地方的问题,与此线程无关。也许您的迁移:
Test.objects.annotate(
    duration=F('date2') - F('date1')
).filter(duration__gt=timedelta(days=365))
from django.db.models import F, Func

Test.objects.annotate(
    duration = Func(F('date2'), F('date1'), function='age')
).filter(duration__gt=timedelta(days=365))