Django ORM:对Datetime字段的timedelta进行筛选
我试图根据两个DateTimeField()的时差来获取帖子,比如说,发布后不到10分钟就被删除的帖子Django ORM:对Datetime字段的timedelta进行筛选,django,django-orm,django-aggregation,Django,Django Orm,Django Aggregation,我试图根据两个DateTimeField()的时差来获取帖子,比如说,发布后不到10分钟就被删除的帖子 class Post(models.Model): ... time_posted = models.DateTimeField() time_deleted = models.DateTimeField(blank=True, null=True) 拿着上面的模型,我试了一下 from datetime import timedelta Post.objects.
class Post(models.Model):
...
time_posted = models.DateTimeField()
time_deleted = models.DateTimeField(blank=True, null=True)
拿着上面的模型,我试了一下
from datetime import timedelta
Post.objects.exclude(deleted__isnull=True).annotate(
delta=F('time_deleted') - F('time_posted')
).filter(delta__lt=timedelta(minutes=10))
并得到一个“TypeError:预期的字符串或缓冲区”。然后我认为这可能是类型的改变(DateTime对象产生Time对象),所以我尝试使用“ExpressionWrapper:
Post.objects.exclude(deleted__isnull=True).annotate(
delta=models.ExpressionWrapper(
F('time_deleted') - F('time_posted'),
output_field=models.TimeField())
).filter(delta__gt=timedelta(minutes=10))
但这也导致了同样的例外
非常感谢您的帮助
编辑
根据@ivan的建议,我尝试了DurationField()。我不再得到异常,但增量始终为“0”
>>post=post.objects.exclude(deleted\u isnull=True)。注释(
delta=ExpressionWrapper(F('deleted')-F('time'),
输出\字段=DurationField())
).first()
>>>发布时间
datetime.datetime(2015,8,24,13,26,50857326,tzinfo=)
>>>post.time\u已删除
datetime.datetime(2015,8,24,13,27,30,521569,tzinfo=)
>>>后三角洲
datetime.timedelta(0)
应改为输出\u字段
kwarg,因为它在Django中存储datetime.timedelta
,而TimeField
存储datetime.time
不过有一个警告:
带有DurationField的算术在大多数情况下都有效。但是,在除PostgreSQL之外的所有数据库上,将DurationField的值与DateTimeField实例上的算术值进行比较将无法按预期工作
在SQLite后端中,DurationField
由存储微秒的bigint
表示:
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'sqlite'
# ...
data_types = {
# ...
'DecimalField': 'decimal',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
# ...
}
因为您使用的是SQLite,所以实际上需要delta
以微秒为单位。请参阅,以了解执行此操作的Func
。您是否尝试使用models.DateTimeField()
作为输出字段?@LaundroMat@omat它可能是models.DurationField
。是的,“DurationField”起作用。非常感谢。我不再收到异常,但增量始终为“0”。请查看问题中的我的编辑。谢谢。本地开发机器上的Sqlite。我将链接到您的案例。
class DatabaseWrapper(BaseDatabaseWrapper):
vendor = 'sqlite'
# ...
data_types = {
# ...
'DecimalField': 'decimal',
'DurationField': 'bigint',
'FileField': 'varchar(%(max_length)s)',
# ...
}