RuntimeWarning: DateTimeField nhận được một datetime ngây thơ


310

Tôi đang cố gắng gửi một thư đơn giản bằng IPython. Tôi chưa thiết lập bất kỳ mô hình nào vẫn nhận được lỗi này. Những gì có thể được thực hiện?

Lỗi: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField đã nhận được một thời gian ngây thơ (2013-09-200 14: 14: 13.698105) trong khi hỗ trợ múi giờ đang hoạt động. Thời gian chạy)

Đã thử: Bước đầu tiên là thêm USE_TZ = Truevào tệp cài đặt của bạn và cài đặt pytz(nếu có thể).

Lỗi đã thay đổi:

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

Câu trả lời:


490

Vấn đề không nằm ở cài đặt Django, mà là vào ngày được chuyển cho mô hình. Đây là cách một đối tượng nhận biết múi giờ trông như thế nào:

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

Và đây là một đối tượng ngây thơ:

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

Vì vậy, nếu bạn đang vượt qua ngày email ở bất cứ đâu (và cuối cùng nó sẽ đến một số mô hình), chỉ cần sử dụng Django now(). Nếu không, thì đó có thể là một vấn đề với gói hiện có lấy ngày không có múi giờ và bạn có thể vá gói, bỏ qua cảnh báo hoặc đặt USE_TZ thành Sai.


8
Bạn viết ở đâu tzinfo=<UTC>, là <UTC>gì? Đó không phải là một cấu trúc cú pháp tôi đã thấy.
jameshfisher 13/2/2015

4
Một chút muộn cho bữa tiệc, nhưng những gì bạn đang thấy là đầu ra từ vỏ. Cụ thể hơn, đó là đầu ra từ phương thức repr của đối tượng datetime , trả về thông tin có thể in của đối tượng.
George Griffin

36
Ở những nơi bạn đang sử dụng datetime.now, hãy thay đổi nó timezone.nowvà thêm from django.utils import timezoneở trên cùng.
Unoti

12
Đối với những người vẫn đang tìm kiếm phần <UTC> đó, bạn có thể sử dụng phần này:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz

Cài đặt của tôi là USE_TZ = True, TIME_ZONE = 'UTC'. Nhưng khi tôi sử dụng timezone.now()nó không hiển thị tzinfo=<UTC>.... Vì vậy, đối tượng datetime này được truyền là một đối tượng ngây thơ. Tại sao nó xảy ra?
dùng3595632

71

Sử dụng hàm django.utils.timezone.make_war để làm cho các đối tượng datetime ngây thơ của bạn biết múi giờ và tránh những cảnh báo đó.

Nó chuyển đổi đối tượng datetime ngây thơ (không có thông tin múi giờ) thành đối tượng có thông tin múi giờ (sử dụng múi giờ được chỉ định trong cài đặt django của bạn nếu bạn không chỉ định rõ ràng là đối số thứ hai):

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>

Cảm ơn câu trả lời này, đó là cách phù hợp nhất với django để biến ngày tháng ngây thơ thành ngày với múi giờ của cài đặt django của tôi :)
sodimel

Có thể đặt cái này trong mô hình lạ không?
Florent

@Florent không cần thay đổi bất cứ điều gì trong các mô hình nếu bạn sử dụng múi giờ utc theo mặc định auto_nowauto_now_addsẽ hoạt động tốt cho các trường datetime. Nếu bạn cần phải có múi giờ nhận biết đối tượng datetime hiện tại trong các mô hình vì một số lý do - sử dụng django.utils.timezone.now()hàm.
dmrz

26

Chỉ cần sửa lỗi để đặt thời gian hiện tại

from django.utils import timezone
import datetime

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

4
và cho datetime.datetime (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor

IMO đây là giải pháp thiết thực nhất
Ramtin

9

Người ta có thể vừa sửa cảnh báo vừa sử dụng múi giờ được chỉ định trong settings.py, có thể khác với UTC.

Ví dụ: trong cài đặt của tôi, tôi có:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

Đây là một giải pháp; lợi thế là str(mydate)cho thời gian chính xác:

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

Một phương pháp tương đương khác đang sử dụng make_aware, xem bài đăng dmrz.



3

Bạn cũng có thể ghi đè cài đặt, đặc biệt hữu ích trong các thử nghiệm:

from django.test import override_settings

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

Điều này sẽ ngăn bạn nhìn thấy cảnh báo, đồng thời bất cứ điều gì trong mã của bạn yêu cầu một mốc thời gian nhận biết múi giờ có thể gây ra cho bạn các vấn đề. Nếu đây là trường hợp, xem câu trả lời kravietz.


2

Nếu bạn đang cố gắng chuyển đổi một datetime ngây thơ thành một datetime với múi giờ trong django, đây là giải pháp của tôi:

>>> 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 là một datetime ngây thơ và t2 là một datetime với múi giờ trong cài đặt của django.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.