RuntimeWarning: DateTimeField recibió una fecha y hora ingenua

310

Estoy tratando de enviar un correo simple usando IPython. No he configurado ningún modelo que todavía reciba este error. ¿Qué se puede hacer?

Error: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField recibió una fecha y hora ingenua (2013-09-04 14: 14: 13.698105) mientras el soporte de zona horaria está activo. RuntimeWarning)

Probado: el primer paso es agregar USE_TZ = Truea su archivo de configuración e instalar pytz(si es posible).

Error cambiado:

(learn)sourabh@sL:~/Django/learn/event$ python manage.py shell
/home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py:53: RuntimeWarning: SQLite received a naive datetime (2013-09-05 00:59:32.181872) while time zone support is active.
  RuntimeWarning)
shifu
fuente

Respuestas:

490

El problema no está en la configuración de Django, sino en la fecha pasada al modelo. Así es como se ve un objeto con reconocimiento de zona horaria:

>>> from django.utils import timezone
>>> import pytz
>>> timezone.now()
datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)

Y aquí hay un objeto ingenuo:

>>> from datetime import datetime
>>> datetime.now()
datetime.datetime(2013, 11, 20, 20, 9, 26, 423063)

Entonces, si está pasando la fecha de correo electrónico en cualquier lugar (y eventualmente llega a algún modelo), solo use Django now(). De lo contrario, probablemente sea un problema con un paquete existente que recupera la fecha sin zona horaria y puede parchear el paquete, ignorar la advertencia o establecer USE_TZ en False.

kravietz
fuente
8
¿Dónde escribes tzinfo=<UTC>, qué es <UTC>? Esa no es una construcción sintáctica que he visto.
jameshfisher
44
Un poco tarde para la fiesta, pero lo que está viendo es la salida del shell. Más específicamente, es la salida del método repr del objeto datetime , que devuelve información imprimible del objeto.
George Griffin
36
En los lugares donde estaba usando datetime.now, cámbielo timezone.nowy agregue from django.utils import timezoneen la parte superior.
Unoti
12
Para aquellos que todavía buscan esa parte <UTC>, pueden usar esto:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz
Mis valores son USE_TZ = True, TIME_ZONE = 'UTC'. Pero cuando lo uso timezone.now()no se muestra tzinfo=<UTC>... Así que este objeto de fecha y hora se pasa como ingenuo. ¿Por que sucede?
user3595632
71

Use la función django.utils.timezone.make_aware para hacer que sus ingenuos datetime sean conscientes de la zona horaria y evitar esas advertencias.

Convierte el objeto de fecha y hora ingenuo (sin información de zona horaria) en el que tiene información de zona horaria (usando la zona horaria especificada en la configuración de django si no la especifica explícitamente como un segundo argumento):

import datetime
from django.conf import settings
from django.utils.timezone import make_aware

naive_datetime = datetime.datetime.now()
naive_datetime.tzinfo  # None

settings.TIME_ZONE  # 'UTC'
aware_datetime = make_aware(naive_datetime)
aware_datetime.tzinfo  # <UTC>
dmrz
fuente
Gracias por esta respuesta, es la forma más compatible con django para transformar fechas ingenuas en fechas con la zona horaria de mi configuración de django :)
sodimel
¿Es posible poner esto en models.py?
Florent
@Florent no hay necesidad de cambiar nada en los modelos si usa la zona horaria utc por defecto, auto_nowy auto_now_addfuncionará bien para los campos de fecha y hora. Si necesita tener un objeto de fecha y hora actual consciente de la zona horaria en los modelos por alguna razón, use la django.utils.timezone.now()función.
dmrz
26

Solo para corregir el error y configurar la hora actual

from django.utils import timezone
import datetime

datetime.datetime.now(tz=timezone.utc) # you can use this value
Sachin G.
fuente
44
y para datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor
OMI, esta es la solución más práctica
Ramtin
9

Uno puede arreglar la advertencia y usar la zona horaria especificada en settings.py, que puede ser diferente de UTC.

Por ejemplo, en mi settings.py tengo:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Aquí hay una solución; La ventaja es que str(mydate)da el tiempo correcto:

>>> from datetime import datetime
>>> from django.utils.timezone import get_current_timezone
>>> mydate = datetime.now(tz=get_current_timezone())
>>> mydate
datetime.datetime(2019, 3, 10, 11, 16, 9, 184106, 
    tzinfo=<DstTzInfo 'Europe/Paris' CET+1:00:00 STD>)
>>> str(mydate)
'2019-03-10 11:16:09.184106+01:00'

Se está utilizando otro método equivalente make_aware, consulte la publicación de dmrz.

Edouard Thiel
fuente
3

También puede anular la configuración, particularmente útil en las pruebas:

from django.test import override_settings

with override_settings(USE_TZ=False):
    # Insert your code that causes the warning here
    pass

Esto evitará que vea la advertencia, al mismo tiempo, cualquier cosa en su código que requiera una fecha y hora consciente de la zona horaria puede causarle problemas. Si este es el caso, vea la respuesta de kravietz.

radtek
fuente
2

Si está tratando de transformar una fecha y hora ingenua en una fecha y hora con zona horaria en django, aquí está mi solución:

>>> import datetime
>>> from django.utils import timezone
>>> t1 = datetime.datetime.strptime("2019-07-16 22:24:00", "%Y-%m-%d %H:%M:%S")
>>> t1
    datetime.datetime(2019, 7, 16, 22, 24)
>>> current_tz = timezone.get_current_timezone()
>>> t2 = current_tz.localize(t1)
>>> t2
    datetime.datetime(2019, 7, 16, 22, 24, tzinfo=<DstTzInfo 'Asia/Shanghai' CST+8:00:00 STD>)
>>>

t1 es una fecha y hora ingenua y t2 es una fecha y hora con zona horaria en la configuración de django.

hcf1425
fuente