Django - DateTimeField 接收到一个 naive datetime。
Django - DateTimeField 接收到一个 naive datetime。
基本上我有以下模型:
class Event(models.Model): start = models.DateTimeField(default=0)
当我尝试使用datetime.datetime.strptime创建对象时,会得到下面的错误:
Event.objects.create(start=datetime.datetime.strptime("02/03/2014 12:00 UTC", "%d/%m/%Y %H:%M %Z")) /usr/local/lib/python2.7/dist-packages/django/db/models/fields/__init__.py:903: RuntimeWarning: DateTimeField Event.start received a naive datetime (2014-03-02 12:00:00) while time zone support is active.
我已经看了很多类似的帖子,但我无法弄清楚为什么即使我提供了UTC (%Z)参数,它仍然会出错。
提前致谢。
admin 更改状态以发布 2023年5月23日
警告信息是由于你正在使用时区,并手动创建日期时间对象。我建议你在settings.py中添加以下内容来将警告转换成错误,这样你就可以更容易地发现这样的异常:
import warnings warnings.filterwarnings('error', r"DateTimeField .* received a naive datetime", RuntimeWarning, r'django\.db\.models\.fields')
说实话我不知道为什么,但是你的日期似乎不太正常(如果你使用timezone.is_aware()
,它应该返回false)。
为了解决你当前的问题,我建议你依靠Django工具来处理时区:
from django.utils import timezone timezone.make_aware(yourdate, timezone.get_current_timezone())
对于我的项目,我创建了一个日期的实用工具类,因为我也面临了这样的问题,你可以看看(尤其是dateFromString
方法):
class DateUtils(object): @classmethod def currentTimezoneDate(cls): """ Returns an aware datetime object based on current timezone. :return: datetime: date """ return timezone.make_aware(datetime.now(), timezone.get_current_timezone()) @classmethod def currentTimezoneOffset(cls): """ Returns the offset (expressed in hours) between current timezone and UTC. :return: int: offset """ offset = cls.currentTimezoneDate().utcoffset() return int(offset.total_seconds() / 60 / 60) @classmethod def UTCDate(cls, year, month, day, hour=0, minute=0, second=0, microsecond=0): """ Creates an aware UTC datetime object. :return: datetime: date """ d = datetime(year, month, day, hour, minute, second, microsecond) return timezone.make_aware(d, timezone.utc) @classmethod def asUTCDate(cls, date): """ Get the UTC version of the given date. :param date: datetime: Date to be converted into UTC :return: datetime UTC date """ if type(date) is Date: return timezone.make_aware(datetime(date.year, date.month, date.day), timezone.utc) if not timezone.is_aware(date): return timezone.make_aware(date, timezone.utc) return date.replace(tzinfo=timezone.utc) @classmethod def getJavaScriptDateFormatForCurrentLocale(cls): """ Return a date mask string that will be understood and used by JavaScript. :return: str: Date mask string for JavaScript. """ f = get_format('SHORT_DATE_FORMAT') return f.replace('Y', 'yyyy').replace('m', 'mm').replace('d', 'dd') @classmethod def getPythonDateFormatForCurrentLocale(cls): """ Return a date mask string that will be understood and used by Python. :return: str: Date mask string for Python. """ f = get_format('SHORT_DATE_FORMAT') return f.replace('Y', '%Y').replace('m', '%m').replace('d', '%d') @classmethod def dateFromString(cls, string, format=None, utc=True): """ Returns a datetime object from the given string. :param string: str: A date string :param format: str: The format of the date :return: datetime: date """ date = datetime.strptime(string, format or cls.getPythonDateFormatForCurrentLocale()) if utc: return cls.asUTCDate(date) return date @classmethod def getFormattedStringForCurrentLocale(cls, date): """ Return a date string formatted using current locale settings. :param date: datetime: :return: str: Formatted Date string. """ return date.strftime(cls.getPythonDateFormatForCurrentLocale()) @classmethod def randomDate(cls, start, end): """ Return a random date between the 2 dates provided. See: http://stackoverflow.com/a/8170651/267719 :param start: datetime: Min date. :param end: datetime: Max date. :return: datetime: Random date in range. """ return start + timedelta(seconds=randint(0, int((end - start).total_seconds()))) @classmethod def hourRange(cls, fromHour, toHour): n = fromHour hRange = [fromHour] while n != toHour: n += 1 if n > 23: n = 0 hRange.append(n) hRange.pop() return hRange