Django - 返回 Post 对象查询在本地时间跨越到前端的月份列表
Posted
技术标签:
【中文标题】Django - 返回 Post 对象查询在本地时间跨越到前端的月份列表【英文标题】:Django - Return a list of months that a query of Post objects spans to front-end in local time 【发布时间】:2022-01-21 20:37:37 【问题描述】:所以我有一个奇怪而有趣的问题。假设我希望能够在本地时间按月将 Facebook 等应用程序上的帖子分组给发送请求的人。假设我在 Django 中有一个 Post
表,其中包含标准的 created
、body
和 author
字段。其中created
是它的创建日期和时间。
假设我想查找用户的所有帖子,以便查询看起来像 Post.objects.filter(author=<some name>)
。我希望能够将它们跨越的日期发回给这些帖子的请求者。这有点棘手的原因是因为 Django 以 UTC 存储,除非给定,否则没有用户时区的概念。
我最初的想法是制作一个类似于/post/<str:author>/<str:timezone>
的网址,然后以某种方式将所有查询的Post
的创建日期转换为该时区并计算出月份。需要时区来涵盖某人在当月最后一天发布的边缘情况。取决于时区,可能是 UTC 的当前月份或下一个月份。
如何找到作者在Post
跨度的请求者时区中的所有月份?
例如,如果有人 ping 网址:/post/James/PST
,假设 James 在 PST 的 11 月发布了 10 次,10 月发布了 20 次。响应应该返回['October', 'November']
我目前正在运行:
Django 3.2.9 Postgresql尝试的解决方案
>>>qs = Post.objects.annotate(
d=RawSQL("to_char(dt at time zone %s, 'YYYY-MM')", [time_zone]),
).values_list("d", flat=True).distinct()
>>>print(qs.query)
SELECT DISTINCT (to_char(dt at time zone PST, 'YYYY-MM')) AS "d" FROM "cheers_post"
【问题讨论】:
这是在哪个数据库上?您的数据库可能会非常有效地进行日期数学运算。 @AKX postgres。我也将此信息添加到我的原始帖子中。 【参考方案1】:我会说您需要了解一些 Postgres 细节,但这似乎可行。
您可以在select *
中看到我的客户端时区是 +03:00(芬兰),并且保存的数据是 UTC (Z
)。
akx=# create table x (id serial, dt timestamptz);
CREATE TABLE
akx=# insert into x (dt) values ('2021-06-01T00:00:00Z');
INSERT 0 1
akx=# select * from x;
id | dt
----+------------------------
1 | 2021-06-01 03:00:00+03
(1 row)
akx=# select distinct to_char(dt at time zone 'PST', 'YYYY-MM') from x;
to_char
---------
2021-05
(1 row)
akx=#
翻译成 Django,也许
tz = "PST"
post_dates = Post.objects.annotate(
d=RawSQL("to_char(dt at time zone %s, 'YYYY-MM')", [tz]),
).values_list("d", flat=True).distinct()
还是附近?
【讨论】:
那我会试一试。你认为只给出PST
的时区就足够了吗?我认为通常它与 javascript 或 Python 上的 Date 对象中的 id 代码一起存储?
显然只有 PST 有效。 ;-) 您可以使用全名(例如Europe/Helsinki
)或缩写(EET
/EEST
),请参阅select * from pg_timezone_names;
...
好吧,Europe/Helsinki
风格的时区标识符也可以工作,所以***.com/a/59430684/51685 可能适合你...
不,您需要明确地执行 print(qs.query)
才能获取 SQL。
你会希望在测试视图中运行它们以避免在损坏的事务中运行:)以上是关于Django - 返回 Post 对象查询在本地时间跨越到前端的月份列表的主要内容,如果未能解决你的问题,请参考以下文章
即使数据库将 0 存储为字段值,Django 查询集对象也返回 None 而不是 0