RuntimeWarning: DateTimeField saf bir tarih aldı


310

IPython kullanarak basit bir posta göndermeye çalışıyorum. Hala bu hatayı alan hiçbir model kurmadım. Ne yapılabilir?

Hata: /home/sourabh/Django/learn/local/lib/python2.7/site-packages/django/db/models/fields/ init .py: 827: RuntimeWarning: DateTimeField saf bir tarih aldı (2013-09-04 14: 14: 13.698105) zaman dilimi desteği etkin durumdayken. ) RuntimeWarning

Denendi: İlk adım, USE_TZ = Trueayarlar dosyanıza eklemek ve yüklemek pytz(mümkünse).

Hata değişti:

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

Yanıtlar:


490

Sorun Django ayarlarında değil , modele geçen tarihte . Saat dilimine duyarlı bir nesne şöyle görünür:

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

Ve işte saf bir nesne:

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

E-posta tarihini herhangi bir yere geçiriyorsanız (ve sonunda bir modele geçiyorsa), sadece Django's'u kullanın now(). Değilse, muhtemelen mevcut bir pakette saat dilimi olmadan tarih getiren bir sorun vardır ve paketi yamalayabilir, uyarıyı yok sayabilir veya USE_TZ değerini False olarak ayarlayabilirsiniz.


8
Nereye yazıyorsun tzinfo=<UTC>, nedir <UTC>? Bu gördüğüm sözdizimsel bir yapı değil.
jameshfisher

4
Partiye biraz geç, ama gördüğünüz kabuktan çıktı . Daha spesifik olarak, nesnenin yazdırılabilir bilgilerini döndüren datetime nesnesinin repr yönteminden çıktıdır .
George Griffin

36
Kullandığınız yerlerde datetime.now, olarak değiştirin timezone.nowve from django.utils import timezoneen üste ekleyin .
Unoti

12
Hala o <UTC> bölümünü arayanlar için şunları kullanabilirsiniz:import pytz datetime.datetime(2013, 11, 20, 20, 8, 7, 127325, tzinfo=pytz.UTC)
Anoyz

Benim ayarlarıdır USE_TZ = True, TIME_ZONE = 'UTC'. Ama kullandığım timezone.now()zaman göstermiyor tzinfo=<UTC>.... Yani bu datetime nesnesi saf biri olarak geçiyor. Neden oluyor?
user3595632

71

Saf datetime nesnelerinizin saat dilimini bilinçli hale getirmek ve bu uyarıları önlemek için django.utils.timezone.make_aware işlevini kullanın .

Saf datetime nesnesini (saat dilimi bilgisi olmadan) saat dilimi bilgisine (django ayarlarınızda açıkça ikinci bir argüman olarak belirtmezseniz belirtilen saat dilimini kullanarak) dönüştürür:

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>

Bu cevap için teşekkürler, naif tarihleri ​​benim django ayarlarımın saat dilimi ile tarihlere dönüştürmenin en django uyumlu yolu :)
sodimel

Bunu models.py'ye koymak mümkün mü?
Florent

@Florent, varsayılan olarak utc saat dilimini kullanırsanız auto_nowve auto_now_adddatetime alanları için iyi çalışırsa , modellerde herhangi bir değişiklik yapmaya gerek yoktur . Herhangi bir nedenden ötürü modellerde saat diliminin geçerli geçerli tarih saat nesnesine sahip olması gerekiyorsa django.utils.timezone.now()işlevini kullanın .
dmrz

26

Sadece geçerli saati ayarlamak için hatayı düzeltmek için

from django.utils import timezone
import datetime

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

4
ve datetime.datetime için (9999, 01, 01, tzinfo = timezone.utc)
I. Yegor

IMO bu en pratik çözüm
Ramtin

9

Bir ikisi düzeltme uyarı olabilir ve UTC farklı olabilir settings.py belirtilen zaman dilimini kullanır.

Örneğin benim settings.py var:

USE_TZ = True
TIME_ZONE = 'Europe/Paris'

İşte bir çözüm; avantajı, str(mydate)doğru zamanı vermesidir:

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

Başka bir eşdeğer yöntem kullanıyor make_aware, bkz. Dmrz post.



3

Ayrıca, özellikle testlerde yararlı olan ayarları geçersiz kılabilirsiniz:

from django.test import override_settings

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

Bu, uyarıyı görmenizi engeller, aynı zamanda kodunuzda saat dilimi farkında bir tarih gerektiren herhangi bir şey size sorun verebilir. Bu durumda, bkz. Kravietz cevabı.


2

Eğer saf bir tarih saatini django'da saat dilimi ile bir tarih saatine dönüştürmeye çalışıyorsanız, işte benim çözümüm:

>>> 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 saf bir tarih ve t2, django ayarlarında saat dilimi olan bir datetime.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.