2012-06-29 11 views
18

Supongo que la administración de zona horaria se agregó a django 1.4, por lo que el problema es bastante nuevo.Cómo funciona la zona horaria de django con model_field's auto_now_add

que utiliza un modelo simple

class Sample(models.Model): 
    ... 
    date_generated = models.DateTimeField(auto_now_add = True) 

Cuando intento para recuperar un registro recién creado su falla.

min_datetime = datetime.now() - timedelta(seconds = 300) 
sample = Sample.objects.get(date_generated__gte = min_datetime) 

y el servidor emite una advertencia.

DateTimeField received a naive datetime (2012-06-29 15:02:15.074000) while time zone support is active. 

Encontré dos soluciones para ese problema.

  1. Desactivar control de zonas horarias en settings.py

    USE_TZ = False 
    

    pero esto no siempre es desierable.

  2. cambiar

    date_generated = models.DateTimeField(auto_now_add = True) 
    

    a

    date_generated = models.DateTimeField(default=datetime.now()) 
    

    es la solución que mantiene control de zonas horarias de trabajo

Respuesta

17

El problema está en su final: datetime.now() no se TZ conscientes, entonces tú eres el que alimenta a un TZ ingenuo. Vea el Django docs on this issue. La razón por la que funciona al establecer default=datetime.now es que está forzando el valor a una fecha de inicio ingenua, por lo que cuando más tarde lo compare con otra fecha de inicio ingenua, no hay ningún problema.

que necesita para obtener el "ahora" de la siguiente manera:

import datetime 
from django.utils.timezone import utc 

now = datetime.datetime.utcnow().replace(tzinfo=utc) 
+6

¿Esto significa que no sólo puede utilizar auto_now o auto_now_add si tengo USE_TZ = verdad? – dannyroa

+5

Parece que 'auto_now' y' auto_now_add' usan inherentemente 'datetime.now'. Parece una extraña omisión por parte de Django insertar instalaciones conscientes de TZ en Django, sin embargo, se pierda esta muy importante, pero el destino de estos dos kwargs ha sido debatido durante mucho tiempo. Mi razonamiento es que se les deja en compatibilidad retroactiva (y para evitar el retroceso), pero no esperen que les enamore. Simplemente configure el kwarg 'predeterminado' con 'utcnow' y no se preocupe por' auto_now' o 'auto_now_add', si desea conocer la fecha y hora de TZ. –

+0

Gracias Chris. No creo que funcione "por defecto" al reemplazar "auto_now", ya que este último siempre actualiza el tiempo para cada guardado, mientras que "predeterminado" es solo cuando el campo no tiene valor. – dannyroa

7

Tenga cuidado de establecer un valor DateTimeField por defecto de datetime.now(), como que calcular un valor único cuando Apache nginx cargas/Django (o cuando se inicia el servidor de desarrollo) y todos los registros posteriores recibirán ese valor.

Siempre use auto_now_add por ese motivo.

+13

Simplemente use 'default = datetime.now' sin corchetes. –

13
utils

Uso de zona horaria de Django

from django.utils import timezone 
date_generated = models.DateTimeField(default=timezone.now) 
+1

Para que otros usuarios vean este hilo: observe cómo la respuesta dice 'ahora' y no' ahora() '. El segundo evaluaría mientras carga el servidor, que no es lo que quiere. – Pieter

Cuestiones relacionadas