Django - Возвращает список месяцев, которые охватывает запрос объектов Post на front-end в местном времени
Итак, у меня есть странная и интересная проблема. Допустим, я хочу иметь возможность группировать посты в приложении типа Facebook по месяцам в местном времени для того, кто послал запрос. Допустим, у меня есть таблица Post
в Django со стандартными полями created
, body
и author
. Где created
- это дата и время ее создания.
Допустим, я хочу найти все сообщения пользователя, поэтому запрос будет выглядеть как Post.objects.filter(author=<some name>)
. Я хочу иметь возможность отправить обратно запросчику эти посты с датами их создания. Причина, по которой это немного сложно, в том, что Django хранит данные в UTC и не имеет понятия о часовом поясе пользователя, если он не указан.
.
Моя первоначальная идея заключалась в том, чтобы сделать url, который был бы чем-то вроде /post/<str:author>/<str:timezone>
, затем как-то преобразовать дату создания для всех запрошенных Post
в этот часовой пояс и вычислить месяцы. Часовой пояс нужен для того, чтобы покрыть крайний случай, когда кто-то пишет в последний день месяца. В зависимости от часового пояса это может быть текущий месяц в UTC или следующий.
Как мне найти все месяцы в часовом поясе запрашивающего, которые Post
охватывает автор?
Например, если кто-то пингует url: /post/James/PST
и, допустим, Джеймс опубликовал 10 раз в ноябре и 20 раз в октябре в PST. Ответ должен вернуть ['October', 'November']
В настоящее время я работаю на:
- Django 3.2.9
- Postgresql
Я бы сказал, что вам нужно опуститься до некоторых специфических особенностей Postgres, но это, кажется, работает.
Вы видите, что часовой пояс моего клиента +03:00 (Финляндия) в select *
, а сохраненные данные были в 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()
или около того?