Django DateTimeField 在时区支持处于活动状态时收到一个天真的日期时间
Django DateTimeField received a naive datetime while time zone support is active
我正在使用 Django 2.2
在我的应用程序中,时区支持由设置文件中的 USE_TZ=True 启用。
我有带有 DateTime 字段 created
的模型。
我需要根据日期过滤数据。日期可以由用户提供,否则将默认为 now()
.
这就是我正在做的
from datetime import datetime, timedelta
from django.utils import timezone
class Generator:
def __init__(self, start_date=None, end_date=None):
if end_date:
self.end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
else:
self.end_date = timezone.now().date()
if start_date:
self.start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
else:
self.start_date = self.end_date - timedelta(days=7)
def get_query(self, d):
query = MyModel.objects.filter(
d__in=d,
created__gte=start_date,
created__lte=end_date
)
return query
但是这是错误的
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2020-02-28 00:00:00) while time zone support is active.
如何解决这个问题?
如果 myday
是一个代表日期的字符串,为了不得到一个简单的日期时间,可以这样直接将它转换成日期:
from time import strptime
myday = date(*strptime(myday, "%Y-%m-%d")[:3])
此方法避免了必须从原始日期时间转换为感知日期时间。
您可以添加以下代码以确保 start_date 和 end_date 具有时区信息。
例如
tz = timezone.get_current_timezone()
start_date = start_date.replace(tzinfo=tz)
end_date = end_date.replace(tzinfo=tz)
启用时区支持后,数据库层预计只会从您的代码中接收可感知的日期时间。当它收到一个天真的日期时间时会出现此警告。这表明您尚未完成时区支持代码的移植。检查 documentation.
您需要使用 make_aware()
函数将原始日期时间更改为您的项目时区日期时间。为此,您必须像下面这样更新您的代码。
from datetime import datetime, timedelta
from django.utils import timezone
class Generator:
def get_mytimezone_date(original_datetime):
new_datetime = datetime.strptime(original_datetime, '%Y-%m-%d')
tz = timezone.get_current_timezone()
timzone_datetime = timezone.make_aware(new_datetime, tz, True)
return timzone_datetime.date()
def __init__(self, start_date=None, end_date=None):
if end_date:
self.end_date = self.get_mytimezone_date(end_date)
else:
self.end_date = timezone.now().date()
if start_date:
self.start_date = self.get_mytimezone_date(start_date)
else:
self.start_date = self.end_date - timedelta(days=7)
def get_query(self, d):
query = MyModel.objects.filter(
d__in=d,
created__gte=start_date,
created__lte=end_date
)
return query
希望对您有所帮助:)
我正在使用 Django 2.2
在我的应用程序中,时区支持由设置文件中的 USE_TZ=True 启用。
我有带有 DateTime 字段 created
的模型。
我需要根据日期过滤数据。日期可以由用户提供,否则将默认为 now()
.
这就是我正在做的
from datetime import datetime, timedelta
from django.utils import timezone
class Generator:
def __init__(self, start_date=None, end_date=None):
if end_date:
self.end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
else:
self.end_date = timezone.now().date()
if start_date:
self.start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
else:
self.start_date = self.end_date - timedelta(days=7)
def get_query(self, d):
query = MyModel.objects.filter(
d__in=d,
created__gte=start_date,
created__lte=end_date
)
return query
但是这是错误的
RuntimeWarning: DateTimeField MyModel.created received a naive datetime (2020-02-28 00:00:00) while time zone support is active.
如何解决这个问题?
如果 myday
是一个代表日期的字符串,为了不得到一个简单的日期时间,可以这样直接将它转换成日期:
from time import strptime
myday = date(*strptime(myday, "%Y-%m-%d")[:3])
此方法避免了必须从原始日期时间转换为感知日期时间。
您可以添加以下代码以确保 start_date 和 end_date 具有时区信息。 例如
tz = timezone.get_current_timezone()
start_date = start_date.replace(tzinfo=tz)
end_date = end_date.replace(tzinfo=tz)
启用时区支持后,数据库层预计只会从您的代码中接收可感知的日期时间。当它收到一个天真的日期时间时会出现此警告。这表明您尚未完成时区支持代码的移植。检查 documentation.
您需要使用 make_aware()
函数将原始日期时间更改为您的项目时区日期时间。为此,您必须像下面这样更新您的代码。
from datetime import datetime, timedelta
from django.utils import timezone
class Generator:
def get_mytimezone_date(original_datetime):
new_datetime = datetime.strptime(original_datetime, '%Y-%m-%d')
tz = timezone.get_current_timezone()
timzone_datetime = timezone.make_aware(new_datetime, tz, True)
return timzone_datetime.date()
def __init__(self, start_date=None, end_date=None):
if end_date:
self.end_date = self.get_mytimezone_date(end_date)
else:
self.end_date = timezone.now().date()
if start_date:
self.start_date = self.get_mytimezone_date(start_date)
else:
self.start_date = self.end_date - timedelta(days=7)
def get_query(self, d):
query = MyModel.objects.filter(
d__in=d,
created__gte=start_date,
created__lte=end_date
)
return query
希望对您有所帮助:)