Así que tengo este modelo Post . Quiero poder recuperar todas las publicaciones que se created en un mes, año en una determinada zona horaria.
Mi objetivo es implementar una función en la que un usuario en cualquier parte del mundo, digamos en PST, pueda obtener todas las publicaciones de otra persona de un mes determinado en su zona horaria. Entonces, digamos que el usuario A está en EST y el usuario B está en PST (3 horas menos que EST). El usuario B quiere ver todas las publicaciones que el usuario A creó en octubre de 2021. Dado que la aplicación mostrará las publicaciones en la zona horaria en la que se encuentra actualmente el usuario (enviamos la fecha y la hora en UTC, luego el front-end se convierte a la hora local), luego el La aplicación solo debe enviar al usuario B todas las publicaciones del usuario A que se crearon en octubre de 2021 PST. Entonces, por ejemplo, si el usuario A (el usuario en EST) hizo una publicación a las 11 p. m. del 31 de octubre de 2021 EST (8 p. m. del 31 de octubre de 2021 PST) y una publicación a la 1 a. ambas publicaciones de vuelta, porque la segunda se hizo en noviembre en EST, pero en octubre en PST.
model.py
class Post(models.Model): uuid = models.UUIDField(primary_key=True) created = models.DateTimeField('Created at', auto_now_add=True) updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True) creator = models.ForeignKey( User, on_delete=models.CASCADE, related_name="post_creator") body = models.CharField(max_length=POST_MAX_LEN) Entonces, por ejemplo, si un usuario crea 10 publicaciones en noviembre, 2 en diciembre de 2021 en PST. Luego tengo una vista que toma month , year y time_zone y digamos que la URL se parece a /post/<int:month>/<int:year>/<str:time_zone> y el usuario hace ping a /post/11/2021/PST , entonces debería devolver las 10 publicaciones de noviembre. ¿Cómo devuelvo todas las publicaciones de un mes y año en una zona horaria determinada, mes y año?
Nota: El caso extremo complicado a tener en cuenta es si publican el último día de un mes muy tarde. Dependiendo de la zona horaria, algo así como 31/12/2021 en UTC podría ser 01/01/2022. Debido a que Django almacena campos de datetime y hora en UTC, lo que se necesita hacer es convertirlo a la zona created time_zone y luego obtener publicaciones del month y year especificados.
Configuración:
Soluciones tentativas
created a la zona horaria especificada y luego hacer time_zone Post.objects.filter(created__in_range=<some range>) Nota
El problema principal parece ser Pyzt, que toma el tiempo en un formato muy específico "Amercian/Los_Angeles" que formateamos. En lugar del formato de zona horaria abreviado como "PST".
Tome el primer momento del mes (medianoche del día 1) en UTC y el primer momento del próximo mes en UTC, ajústelos con la zona horaria que desee, haga una consulta posted__range=(a, b)?
Esto podría funcionar (pero las matemáticas de fechas son complicadas...).
Esto requiere python-dateutil para que el cálculo de la hora de end sea sólido.
import datetime import pytz from dateutil.relativedelta import relativedelta from django.utils import timezone year = 2021 month = 6 tz = pytz.timezone("America/Los_Angeles") start = datetime.datetime(year, month, 1) end = start + relativedelta(months=1) start_as_tz_in_utc = tz.localize(start).astimezone(pytz.utc) end_as_tz_in_utc = tz.localize(end).astimezone(pytz.utc) print(start_as_tz_in_utc, end_as_tz_in_utc, sep="\n")que imprime
2021-06-01 07:00:00+00:00 2021-07-01 07:00:00+00:00lo que parece correcto.
Entonces usted puede hacer una consulta como
posts = Post.objects.filter(created__range=( start_as_tz_in_utc, end_as_tz_in_utc, ))Yo intentaría algo como esto:
Suponiendo que está pasando un mes dado como mes_dado y año dado como año_dado y zona horaria dada como zona_horaria dada
Model_Name.objects.filter(created.split('/',4)[2]=given_month,created.split('/',4)[3]=given_year, created.split('/',4)[4]=given_timezone)Esto debería obtener el valor de la sección de mes y año y zona horaria de su publicación. Puede que tengas que jugar con lo que te di. También podría ser mejor agregar una relación de usuario a publicación para que pueda filtrar al usuario por publicaciones con mi respuesta dada. En la mayoría de los casos, esto será mucho más eficiente, suponiendo que haya más publicaciones que usuarios. Esto debería ponerte en el camino correcto.
Considere guardar el registro en fecha y hora UTC, no intente guardar ningún desplazamiento de zona horaria. simplemente registre la hora en que los datos llegaron al servidor en UTC y deje que el navegador o su aplicación los traduzca a su zona horaria configurada. No importa si su usuario está en China creó una publicación y luego se mudó a Nueva York al día siguiente y leyó la publicación creada anteriormente, el created_at datetime será el mismo para ambas ubicaciones porque es universal. Entonces, si el usuario B quiere recuperar los datos que el usuario A registró desde octubre, será tan fácil consultar created_at::date>="2021-10-01"