viewset route framework filters detail django django-rest-framework

route - django rest framework request



Representantes/analizadores conscientes de la zona horaria de Django-rest-framework (3)

Estoy creando una aplicación que serviría a personas ubicadas en diferentes lugares del mundo.
Estoy usando Django-Rest-Framwork para la comunicación entre los clientes y el servidor.
Todos los valores de DateTime se guardan en la base de datos como UTC (tengo USE_TZ = True y TIME_ZONE = ''Greenwich'' en settings.py).

Obtendré del usuario su zona horaria local.

Para probar el reconocimiento de zona horaria en DRF, escribí este middleware con zona horaria fija:

import pytz from django.utils import timezone class TimezoneMiddleware(object): def process_request(self, request): timezone.activate(pytz.timezone("Asia/Jerusalem"))

El problema es:
Tengo un caso en el que recibo de los campos "start_time" y "end_time" del usuario que UnicodeJSONRenderer de ModelSerializer en la zona horaria LOCAL del usuario que se UnicodeJSONRenderer a través de UnicodeJSONRenderer a un ModelSerializer y luego se guarda en la base de datos. Sin embargo, se guardan como si estuvieran en UTC .

En este punto, esperaría que el serializador (o analizador) tratara la entrada de datetime del usuario como datetime que debe convertirse de "Asia / Jerusalén" a UTC antes de guardar en la base de datos desde que realicé timezone.activate(pytz.timezone("Asia/Jerusalem")) .

Lo mismo ocurre cuando los datos se analizan en la respuesta a través de JSONParser .
Mientras espera que los campos DateTime en el JSON devuelto estén en la zona horaria activada en el middleware, se devuelven como UTC.

¿Cómo puedo lograr eso fácilmente en DRF?


Desde Django REST Framework v3.8.0 (lanzado en mayo de 2018), ya no necesita un DateTimeField personalizado.

En versiones anteriores, Django REST Framework solo convertía datetime nativo a timetime dat dado a hora dat a cuando analiza la fecha ( DateTimeField.to_internal_value() ), pero no la convierte al representar el campo datatime ( DateTimeField.to_representation() ). This se soluciona en DRF v3.8.0.

Es posible que deba cambiar la siguiente configuración:

  1. USE_TZ debe ser True
  2. configurar TIME_ZONE para especificar una zona horaria predeterminada
  3. establezca REST_FRAMEWORK.DATETIME_FORMAT en el formato que se ajuste a su código de frontend.

La respuesta de @yakxxx parece ser la mejor solución. Lo estoy publicando nuevamente después de actualizarlo para que funcione con las versiones más recientes de restframework

dentro de mi directorio (common / serializers.py)

from rest_framework import serializers from django.utils import timezone class DateTimeFieldWihTZ(serializers.DateTimeField): def to_representation(self, value): value = timezone.localtime(value) return super(DateTimeFieldWihTZ, self).to_representation(value)

Dentro de mi aplicacion

from common.serializers import DateTimeFieldWihTZ class MyObjectSerializer(serializers.ModelSerializer): start = DateTimeFieldWihTZ(format=''%d %b %Y %I:%M %p'') end = DateTimeFieldWihTZ(format=''%d %b %Y %I:%M %p'')


Tuve el mismo problema y lo resolví agregando un nuevo tipo de campo:

class DateTimeTzAwareField(serializers.DateTimeField): def to_native(self, value): value = timezone.localtime(value) return super(DateTimeTzAwareField, self).to_native(value)

Y ahora puedes usarlo en ModelSerializer :

class XSerializer(serializers.ModelSerializer): start = DateTimeTzAwareField() end = DateTimeTzAwareField() class Meta: model = XModel fields = ( ''id'', ''start'', ''end'', )