Django:使用自创建对象以来的秒数注释QuerySet

我有一个模型,叫它Foo,它有一个属性created_at,它记录了创建实例的时间(UTC)。 我想用此模型注释一个查询集,该查询集自创建返回的每个项目以来经过的秒数。

(更确切地说,我想根据商品的打开时间来“打折”商品,并具有可配置的过时时间,但是如果可以得到自创建以来的秒数,我可以进行计算)

我尝试了一些显而易见的事情,例如

Foo.objects.annotate(time_since_create=now-F('created_at'))

Foo.objects.annotate(time_since_create=now.timestamp()-F('created_at'))

(其中now is utc.localize(datetime.utcnow())`)

但是这些让我得到AttributeError: 'float' object has no attribute 'tzinfo',这表明日期上的DB算术比我想象的要复杂一些。

很明显,我可以在python中执行此算法,即

[(id,now-created_at) for id,created_at in Foo.objects.values_list("id","created_at")]

但是如果我能在查询集中找到它,那就更好了。

yszwei02 回答:Django:使用自创建对象以来的秒数注释QuerySet

您可以使用的一种解决方案是Django queryset中的额外功能。如果您需要所有记录的差异,则无需执行注释或汇总。

我的数据库是mysql。所以我在几秒钟内使用了TIMESTAMPDIFF。 TIMESTAMPDIFF来自mysql数据库。您需要在下面的查询集中使用数据库中可用的功能。希望这会有所帮助。

访问https://docs.djangoproject.com/en/2.2/ref/models/querysets/#s-extra

time_since_create = {"time_since_create": """TIMESTAMPDIFF(SECOND,created_at,now())"""}
objs = Foo.objects.extra(select=time_since_create).values('name','time_since_create')
str(objs.query)

如果您打印sql查询,它将是这样的。

SELECT (TIMESTAMPDIFF(SECOND,now())) AS `time_since_create`,`foo`.`name` FROM `foo`
,

第一种方法

您可以像这样过滤查询集

time_threshold =  datetime.now() - timedelta(munutes=40)
Foo.objects.filter(created_at__lte=time_threshold)

Source

输出

> <QuerySet [<Foo: 2019-11-18 20:56:16.228271+00:00>,<Foo: 2019-11-18
> 20:56:31.842079+00:00>,<Foo: 2019-11-18 20:56:32.761461+00:00>,<Foo:
> 2019-11-18 20:57:04.612091+00:00>,<Foo: 20 19-11-18
> 20:57:11.401817+00:00>,<Foo: 2019-11-18 21:00:12.794631+00:00>,<Foo:
> 2019-11-18 21:00:14.935930+00:00>,<Foo: 2019-11-18
> 21:00:59.107677+00:00>,<Foo: 2019-11-18 21:01:27.5 90956+00:00>]>

第二种方法

您可以在模型中创建一个def,以占用自创建以来经过的时间 然后使用它

class Foo(models.Model):
    created_at = models.DateTimeField(auto_now_add=True)

    def time_elapsed_since_create(self):
        return datetime.now(timezone.utc) - self.created_at

    def __str__(self):
        return str(self.created_at)

输出

>>> bar = Foo.objects.create()
>>> print(bar.time_elapsed_since_create())
0:00:09.480279
>>> print(bar.time_elapsed_since_create())
0:00:10.560474
>>> print(bar.time_elapsed_since_create())
0:00:11.248255

>>> print(type(bar.time_elapsed_since_create()))
<class 'datetime.timedelta'>

用于获取所有早于60秒的Foos的功能

>>> for i in Foo.objects.all():
...     if i.time_elapsed_since_create() > timedelta(seconds=60):
...             print(i.id,i.created_at,i.time_elapsed_since_create())
...
1 2019-11-18 20:56:16.228271+00:00 0:13:12.512974
2 2019-11-18 20:56:31.842079+00:00 0:12:56.899166
3 2019-11-18 20:56:32.761461+00:00 0:12:55.979784
4 2019-11-18 20:57:04.612091+00:00 0:12:24.129154
5 2019-11-18 20:57:11.401817+00:00 0:12:17.340419
6 2019-11-18 21:00:12.794631+00:00 0:09:15.947605
7 2019-11-18 21:00:14.935930+00:00 0:09:13.806306
8 2019-11-18 21:00:59.107677+00:00 0:08:29.634559
9 2019-11-18 21:01:27.590956+00:00 0:08:01.152280
本文链接:https://www.f2er.com/3077959.html

大家都在问