RuntimeWarning: DateTimeField hat eine naive Datums- / Uhrzeitangabe erhalten

310

Ich versuche, eine einfache Mail mit IPython zu senden. Ich habe keine Modelle eingerichtet, bei denen dieser Fehler noch auftritt. Was kann getan werden?

Fehler: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField hat eine naive Datumszeit erhalten (2013-09-04 14: 14: 13.698105), während die Zeitzonenunterstützung aktiv ist. RuntimeWarning)

Versucht: Der erste Schritt besteht darin USE_TZ = True, Ihre Einstellungsdatei hinzuzufügen und zu installieren pytz(falls möglich).

Fehler geändert:

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

Antworten:

490

Das Problem liegt nicht in den Django-Einstellungen, sondern in dem Datum, das an das Modell übergeben wurde. So sieht ein zeitzonenbewusstes Objekt aus:

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

Und hier ist ein naives Objekt:

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

Wenn Sie also irgendwo ein E-Mail-Datum übergeben (und es irgendwann zu einem Modell kommt), verwenden Sie einfach Djangos now(). Wenn nicht, liegt wahrscheinlich ein Problem mit einem vorhandenen Paket vor, bei dem das Datum ohne Zeitzone abgerufen wird. Sie können das Paket patchen, die Warnung ignorieren oder USE_TZ auf False setzen.

Kravietz
quelle
8
Wo schreibst du tzinfo=<UTC>, was ist <UTC>? Das ist kein syntaktisches Konstrukt, das ich gesehen habe.
Jameshfisher
4
Ein bisschen spät zur Party, aber was Sie sehen, wird von der Shell ausgegeben . Insbesondere ist es die Ausgabe der repr- Methode des datetime-Objekts , die druckbare Informationen des Objekts zurückgibt.
George Griffin
36
datetime.nowÄndern Sie es an den Stellen, an denen Sie es verwendet haben , in timezone.nowund fügen Sie es from django.utils import timezoneoben hinzu.
Unoti
12
Für diejenigen, die noch nach diesem <UTC> Teil suchen, können Sie dies verwenden:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz
Meine Einstellungen sind USE_TZ = True, TIME_ZONE = 'UTC'. Aber wenn ich es benutze, wird timezone.now()es nicht tzinfo=<UTC>angezeigt ... Also wird dieses Datum / Uhrzeit-Objekt als naiv übergeben. Warum passiert das?
user3595632
71

Verwenden Sie die Funktion django.utils.timezone.make_aware , um Ihre naiven Datetime-Objekte auf die Zeitzone aufmerksam zu machen und diese Warnungen zu vermeiden.

Es konvertiert ein naives Datum / Uhrzeit-Objekt (ohne Zeitzoneninformationen) in ein Objekt mit Zeitzoneninformationen (unter Verwendung der in Ihren Django-Einstellungen angegebenen Zeitzone, wenn Sie diese nicht explizit als zweites Argument angeben):

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
quelle
Vielen Dank für diese Antwort, es ist die django-konformeste Möglichkeit, naive Daten in Daten mit der Zeitzone meiner Django-Einstellungen umzuwandeln :)
sodimel
Ist es möglich, dies in models.py zu setzen?
Florent
@Florent gibt es keine Notwendigkeit zu ändern nichts in Modellen , wenn Sie standardmäßig UTC - Zeitzone verwenden, auto_nowund auto_now_addwerden für Datetime - Felder funktionieren. Wenn Sie aus irgendeinem Grund ein zeitzonenbewusstes aktuelles Datum / Uhrzeit-Objekt in Modellen benötigen, verwenden Sie die django.utils.timezone.now()Funktion.
dmrz
26

Nur um den Fehler zu beheben, um die aktuelle Zeit einzustellen

from django.utils import timezone
import datetime

datetime.datetime.now(tz=timezone.utc) # you can use this value
Sachin G.
quelle
4
und für datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor
IMO ist dies die praktischste Lösung
Ramtin
9

Man kann sowohl fix die Warnung und verwenden Sie die Zeitzone in settings.py angegeben, die von UTC unterschiedlich sein könnten.

Zum Beispiel in meiner settings.py habe ich:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Hier ist eine Lösung; Der Vorteil ist, dass str(mydate)die richtige Zeit angegeben wird:

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

Eine andere äquivalente Methode ist die Verwendung make_aware, siehe dmrz post.

Edouard Thiel
quelle
3

Sie können auch Einstellungen überschreiben, die besonders bei Tests nützlich sind:

from django.test import override_settings

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

Dies verhindert, dass Sie die Warnung sehen. Gleichzeitig kann alles in Ihrem Code, das eine zeitzonenbezogene Datums- / Uhrzeitangabe erfordert, zu Problemen führen. Wenn dies der Fall ist, siehe kravietz Antwort.

radtek
quelle
2

Wenn Sie versuchen, eine naive Datumszeit in eine Datumszeit mit Zeitzone in Django umzuwandeln, ist hier meine Lösung:

>>> 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 ist eine naive Datumszeit und t2 ist eine Datumszeit mit Zeitzone in den Einstellungen von Django.

hcf1425
quelle