RuntimeWarning: DateTimeField ได้รับ datetime ไร้เดียงสา


310

ฉันพยายามส่งจดหมายอย่างง่ายโดยใช้ IPython ฉันไม่ได้ตั้งค่ารุ่นใด ๆ ที่ยังคงได้รับข้อผิดพลาดนี้ สิ่งที่สามารถทำได้?

ข้อผิดพลาด: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py : 827: RuntimeWarning: DateTimeField ได้รับข้อมูลที่ไร้เดียงสา (2013-09-04) 14: 14: 13.698105) ขณะที่การสนับสนุนเขตเวลาเปิดใช้งานอยู่ RuntimeWarning)

พยายาม: ขั้นตอนแรกคือการเพิ่มUSE_TZ = Trueไฟล์การตั้งค่าของคุณและติดตั้งpytz(ถ้าเป็นไปได้)

ข้อผิดพลาดมีการเปลี่ยนแปลง:

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

คำตอบ:


489

ปัญหาไม่ได้อยู่ในการตั้งค่า Django แต่ในวันที่ผ่านไปยังรุ่น นี่คือลักษณะของวัตถุที่รับรู้เขตเวลา:

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

และนี่คือวัตถุที่ไร้เดียงสา:

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

ดังนั้นถ้าคุณจะผ่านวันที่อีเมลได้ทุกที่ (และในที่สุดก็จะได้รับบางรุ่น) เพียงแค่ใช้ของ now()Django หากไม่เป็นเช่นนั้นอาจเป็นปัญหากับแพ็คเกจที่มีอยู่ซึ่งดึงข้อมูลวันที่โดยไม่มีเขตเวลาและคุณสามารถแก้ไขแพ็กเกจไม่สนใจคำเตือนหรือตั้งค่า USE_TZ เป็น False


8
ที่คุณเขียนtzinfo=<UTC>คือ<UTC>อะไร นั่นไม่ใช่โครงสร้างประโยคที่ฉันได้เห็น
jameshfisher

4
สายไปงานปาร์ตี้ แต่สิ่งที่คุณเห็นคือเอาท์พุทจากเปลือก โดยเฉพาะอย่างยิ่งมันเป็นผลลัพธ์จากวัตถุ datetime ของReprวิธีการที่ผลตอบแทนข้อมูลพิมพ์ของวัตถุ
George Griffin

36
ในสถานที่ที่คุณใช้อยู่datetime.nowให้เปลี่ยนเป็นtimezone.nowและเพิ่มfrom django.utils import timezoneที่ด้านบน
Unoti

12
สำหรับผู้ที่ยังคงมองหาส่วน <UTC> นั้นคุณสามารถใช้สิ่งนี้:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz

การตั้งค่าของฉัน,USE_TZ = True TIME_ZONE = 'UTC'แต่เมื่อฉันใช้timezone.now()มันจะไม่แสดงtzinfo=<UTC>.... ดังนั้นวัตถุ datetime นี้จะถูกส่งผ่านอย่างไร้เดียงสา ทำไมมันเกิดขึ้น
user3595632

71

ใช้ฟังก์ชั่นdjango.utils.timezone.make_awareเพื่อทำให้วัตถุที่ไร้เดียงสาของคุณทราบเวลาและหลีกเลี่ยงคำเตือนเหล่านั้น

มันแปลงวัตถุไร้เดียงสา datetime (ไม่มีข้อมูลเขตเวลา) เป็นหนึ่งที่มีข้อมูลเขตเวลา (ใช้เขตเวลาที่ระบุไว้ในการตั้งค่า django ของคุณถ้าคุณไม่ได้ระบุอย่างชัดเจนว่าเป็นอาร์กิวเมนต์ที่สอง):

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>

ขอขอบคุณสำหรับคำตอบนี้เป็นวิธีที่ดีที่สุดที่จะเปลี่ยนวันที่ไร้เดียงสาให้เป็นวันที่ด้วยเขตเวลาของการตั้งค่า django ของฉัน :)
23915

เป็นไปได้ไหมที่จะใส่ไว้ใน models.py?
Florent

@ ที่ดีขึ้นไม่จำเป็นต้องเปลี่ยนแปลงอะไรในรุ่นถ้าคุณใช้ utc timezone ตามค่าเริ่มต้นauto_nowและauto_now_addจะทำงานได้ดีสำหรับเขตข้อมูลวันที่และเวลา หากคุณต้องการให้วัตถุวันที่และเวลาปัจจุบันทราบเขตเวลาในรูปแบบด้วยเหตุผลบางอย่าง - django.utils.timezone.now()ฟังก์ชั่นการใช้งาน
dmrz

26

เพียงเพื่อแก้ไขข้อผิดพลาดเพื่อตั้งเวลาปัจจุบัน

from django.utils import timezone
import datetime

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

4
และสำหรับ datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor

IMO นี่เป็นวิธีแก้ปัญหาที่ได้ผลที่สุด
Ramtin

9

หนึ่งสามารถแก้ไขคำเตือนและใช้เขตเวลาที่ระบุใน settings.py ซึ่งอาจแตกต่างจาก UTC

ตัวอย่างเช่นใน settings.py ฉันมี:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

นี่คือทางออก; ข้อดีคือstr(mydate)ให้เวลาที่ถูกต้อง:

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

อีกวิธีที่เทียบเท่าใช้คือmake_awareดูโพสต์ dmrz



3

นอกจากนี้คุณยังสามารถแทนที่การตั้งค่าซึ่งมีประโยชน์อย่างยิ่งในการทดสอบ:

from django.test import override_settings

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

สิ่งนี้จะป้องกันไม่ให้คุณเห็นคำเตือนในเวลาเดียวกันสิ่งใดในรหัสของคุณที่จำเป็นต้องใช้เวลาที่ตระหนักถึงเขตเวลาอาจทำให้คุณมีปัญหา หากเป็นกรณีนี้ให้ดูคำตอบ kravietz


2

หากคุณพยายามที่จะแปลงวันที่และเวลาที่ไร้เดียงสาเป็นช่วงเวลาที่มีเขตเวลาใน django นี่คือวิธีการแก้ปัญหาของฉัน:

>>> 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 เป็นวันที่ไร้เดียงสาและ t2 เป็นช่วงเวลาที่มีเขตเวลาในการตั้งค่าของ django

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.