RuntimeWarning: DateTimeField ha ricevuto un datetime ingenuo


310

Sto cercando di inviare una semplice e-mail utilizzando IPython. Non ho ancora impostato alcun modello con questo errore. Cosa si può fare?

Errore: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField ha ricevuto un datetime ingenuo (2013-09-04 14: 14: 13.698105) mentre il supporto del fuso orario è attivo. RuntimeWarning)

Provato: il primo passo è aggiungere USE_TZ = Trueal file delle impostazioni e installarlo pytz(se possibile).

Errore modificato:

(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)

Risposte:


490

Il problema non è nelle impostazioni di Django, ma nella data passata al modello. Ecco come appare un oggetto sensibile al fuso orario:

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

Ed ecco un oggetto ingenuo:

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

Quindi, se passi la data e-mail ovunque (e alla fine arriva a qualche modello), usa solo Django now(). In caso contrario, probabilmente è un problema con un pacchetto esistente che recupera la data senza fuso orario e puoi correggere il pacchetto, ignorare l'avviso o impostare USE_TZ su False.


8
Dove scrivi tzinfo=<UTC>, cos'è <UTC>? Non è un costrutto sintattico che ho visto.
jameshfisher,

4
Un po 'tardi per la festa, ma quello che stai vedendo è l' output dalla shell. Più specificamente, è l'output del metodo repr dell'oggetto datetime che restituisce informazioni stampabili sull'oggetto.
George Griffin,

36
Nei luoghi in cui lo stavi utilizzando datetime.now, modificalo in timezone.nowe aggiungilo from django.utils import timezonein alto.
Unoti,

12
Per coloro che import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
stanno

Le mie impostazioni sono USE_TZ = True, TIME_ZONE = 'UTC'. Ma quando lo uso timezone.now()non mostra tzinfo=<UTC>.... Quindi questo oggetto datetime viene passato come ingenuo. Perché succede?
user3595632

71

Utilizzare la funzione django.utils.timezone.make_aware per rendere consapevoli il fuso orario degli oggetti datetime ingenui ed evitare tali avvisi.

Converte l'oggetto datetime ingenuo (senza informazioni sul fuso orario) in quello che ha informazioni sul fuso orario (utilizzando il fuso orario specificato nelle impostazioni di django se non lo si specifica esplicitamente come secondo argomento):

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>

Grazie per questa risposta, è il modo più conforme a django per trasformare date ingenue in date con il fuso orario delle mie impostazioni di django :)
sodimel

È possibile inserirlo in models.py?
Florent il

@Florent non è necessario modificare nulla nei modelli se si utilizza il fuso orario utc per impostazione predefinita auto_nowe auto_now_addfunzionerà perfettamente per i campi datetime. Se per qualche motivo è necessario disporre dell'oggetto datetime corrente in base al fuso orario nei modelli, utilizzare la django.utils.timezone.now()funzione.
dmrz,

26

Solo per correggere l'errore per impostare l'ora corrente

from django.utils import timezone
import datetime

datetime.datetime.now(tz=timezone.utc) # you can use this value

4
e per datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor

IMO questa è la soluzione più pratica
Ramtin il

9

Uno può sia correggere l'avviso sia usare il fuso orario specificato in settings.py, che potrebbe essere diverso da UTC.

Ad esempio nel mio settings.py ho:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Ecco una soluzione; il vantaggio è che str(mydate)dà l'ora corretta:

>>> 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'

Un altro metodo equivalente sta usando make_aware, vedi dmrz post.



3

Puoi anche ignorare le impostazioni, particolarmente utili nei test:

from django.test import override_settings

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

Questo ti impedirà di vedere l'avvertimento, allo stesso tempo qualsiasi cosa nel tuo codice che richiede un datetime consapevole del fuso orario può darti problemi. In questo caso, vedere la risposta di kravietz.


2

Se stai cercando di trasformare un datetime ingenuo in un datetime con fuso orario in django, ecco la mia soluzione:

>>> 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 è un datetime ingenuo e t2 è un datetime con fuso orario nelle impostazioni di django.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.