在 Django + Python 3 中格式化用于注释计数的日期

Ron*_*eld 5 python django datetime django-annotate

我目前正在尝试根据它们出现的次数来注释和计算一些日期。

visits = Subs.objects.filter(camp=campdata, timestamp__lte=datetime.datetime.today(), timestamp__gt=datetime.datetime.today()-datetime.timedelta(days=30)).\
values('timestamp').annotate(count=Count('timestamp'))
Run Code Online (Sandbox Code Playgroud)

如果我在 for 循环中打印这个,

for a in visits:
  print(a)
Run Code Online (Sandbox Code Playgroud)

我会在 Json 中取回以下内容。

{'timestamp': datetime.datetime(2018, 10, 5, 15, 16, 25, 130966, tzinfo=<UTC>), 'count': 1}
{'timestamp': datetime.datetime(2018, 10, 5, 15, 16, 45, 639464, tzinfo=<UTC>), 'count': 1}
{'timestamp': datetime.datetime(2018, 10, 6, 8, 43, 24, 721050, tzinfo=<UTC>), 'count': 1}
{'timestamp': datetime.datetime(2018, 10, 7, 4, 54, 59, tzinfo=<UTC>), 'count': 1}
Run Code Online (Sandbox Code Playgroud)

这是一个正确的方向,但是,它正在计数到第二个......我只需要几天,这样发生在 2018、10、5 的事件就会被计数:例如 2。

谁能引导我走向正确的方向?

此外,将日期转换为对 json/api 更友好的最“django”方式是什么?

我理想的 json 返回类似于

{'timestamp': 2018-10-5, 'count': 2}
Run Code Online (Sandbox Code Playgroud)

谢谢!

sol*_*oke 7

您可以使用TruncDate注释来实现这一点:

visits = Subs.objects.annotate(date=TruncDate('timestamp')).filter(
    camp=campdata, 
    date__lte=datetime.datetime.today(), 
    date__gt=datetime.datetime.today() - datetime.timedelta(days=30)
).values('date').annotate(count=Count('date'))
Run Code Online (Sandbox Code Playgroud)

至于你关于序列化 JSON 日期的问题,Django 提供了DjangoJSONEncoder帮助:

import json
from django.core.serializers.json import DjangoJSONEncoder

json.dumps(list(visits), cls=DjangoJSONEncoder)
Run Code Online (Sandbox Code Playgroud)