RuntimeWarning: DateTimeField menerima datetime yang naif


310

Saya mencoba mengirim surat sederhana menggunakan IPython. Saya belum menyiapkan model apa pun yang masih mengalami kesalahan ini. Apa yang bisa dilakukan?

Kesalahan: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField menerima datetime naif (2013-09-04 14: 14: 13.698105) ketika dukungan zona waktu aktif. RuntimeWarning)

Mencoba: Langkah pertama adalah menambahkan USE_TZ = Trueke file pengaturan Anda dan menginstal pytz(jika mungkin).

Kesalahan berubah:

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

Jawaban:


490

Masalahnya bukan pada pengaturan Django, tetapi pada tanggal diteruskan ke model. Beginilah bentuk objek yang sadar zona waktu:

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

Dan inilah benda naif:

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

Jadi, jika Anda melewati tanggal email di mana saja (dan itu akhirnya sampai pada beberapa model), cukup gunakan Django now(). Jika tidak, maka itu mungkin masalah dengan paket yang ada yang mengambil tanggal tanpa zona waktu dan Anda dapat menambal paket, mengabaikan peringatan atau mengatur USE_TZ ke False.


8
Di mana Anda menulis tzinfo=<UTC>, apa itu <UTC>? Itu bukan konstruksi sintaksis yang pernah saya lihat.
jameshfisher

4
Agak terlambat ke pesta, tetapi apa yang Anda lihat adalah output dari shell. Lebih khusus, itu adalah output dari metode repr objek datetime , yang mengembalikan informasi cetak objek
George Griffin

36
Di tempat-tempat di mana Anda menggunakan datetime.now, ubah timezone.now, dan tambahkan from django.utils import timezonedi bagian atas.
Unoti

12
Bagi mereka yang masih mencari bagian <UTC> itu, Anda dapat menggunakan ini:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz

Pengaturan saya USE_TZ = True, TIME_ZONE = 'UTC'. Tetapi ketika saya menggunakannya timezone.now()tidak menunjukkan tzinfo=<UTC>.... Jadi objek datetime ini dilewatkan sebagai naif. Mengapa itu terjadi?
user3595632

71

Gunakan fungsi django.utils.timezone.make_aware untuk membuat zona waktu objek naif Anda sadar dan menghindari peringatan tersebut.

Ini mengubah objek datetime naif (tanpa info zona waktu) ke objek yang memiliki info zona waktu (menggunakan zona waktu yang ditentukan dalam pengaturan Django Anda jika Anda tidak menentukannya secara eksplisit sebagai argumen kedua):

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>

Terima kasih atas jawaban ini, ini adalah cara yang paling sesuai dengan django untuk mengubah tanggal yang naif menjadi tanggal dengan zona waktu pengaturan django saya :)
sodimel

Apakah mungkin untuk meletakkan ini di models.py?
Florent

@Florent tidak perlu mengubah apa pun dalam model jika Anda menggunakan utc timezone secara default, auto_nowdan auto_now_addakan berfungsi dengan baik untuk bidang datetime. Jika Anda perlu memiliki zona waktu sadar objek datetime saat ini dalam model untuk beberapa alasan - gunakan django.utils.timezone.now()fungsi.
dmrz

26

Hanya untuk memperbaiki kesalahan untuk mengatur waktu saat ini

from django.utils import timezone
import datetime

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

4
dan untuk datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor

IMO ini adalah solusi paling praktis
Ramtin

9

Seseorang dapat memperbaiki peringatan dan menggunakan zona waktu yang ditentukan dalam settings.py, yang mungkin berbeda dari UTC.

Sebagai contoh di settings.py saya saya punya:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Ini solusinya; Keuntungannya adalah str(mydate)memberikan waktu yang tepat:

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

Metode lain yang setara adalah menggunakan make_aware, lihat posting dmrz.



3

Anda juga dapat mengesampingkan pengaturan, terutama berguna dalam pengujian:

from django.test import override_settings

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

Ini akan mencegah Anda dari melihat peringatan, pada saat yang sama segala sesuatu dalam kode Anda yang memerlukan waktu sadar zona waktu dapat memberi Anda masalah. Jika ini masalahnya, lihat jawaban kravietz.


2

Jika Anda mencoba mengubah datetime naif menjadi datetime dengan zona waktu di Django, berikut adalah solusi saya:

>>> 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 adalah datetime naif dan t2 adalah datetime dengan zona waktu di pengaturan Django.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.