【问题标题】:Django DateTimeField received a naive datetime while time zone support is active时区支持处于活动状态时,Django DateTimeField 收到一个天真的日期时间
【发布时间】:2020-06-19 01:30:41
【问题描述】:

我正在使用 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.

我怎样才能解决这个问题?

【问题讨论】:

    标签: django django-i18n django-timezone


    【解决方案1】:

    启用时区支持后,数据库层只希望从您的代码中接收可感知的日期时间。当它收到一个简单的日期时间时会出现此警告。这表明您尚未完成移植代码以获得时区支持。检查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
    

    希望对你有帮助:)

    【讨论】:

      【解决方案2】:

      您可以添加以下代码以确保 start_date 和 end_date 具有时区信息。 例如

      tz = timezone.get_current_timezone()
      
      start_date = start_date.replace(tzinfo=tz)
      end_date = end_date.replace(tzinfo=tz)
      

      【讨论】:

        【解决方案3】:

        为了不得到一个简单的日期时间,如果myday是一个代表日期的字符串,直接将其转换为日期:

        from time import strptime
        
        myday = date(*strptime(myday, "%Y-%m-%d")[:3])
        

        这种方法避免了从幼稚到有意识的日期时间的转换。

        【讨论】:

          猜你喜欢
          • 2019-07-23
          • 2014-12-03
          • 2016-10-03
          • 2012-07-18
          • 2020-10-13
          • 1970-01-01
          • 2014-03-28
          • 2019-08-06
          • 2014-01-29
          相关资源
          最近更新 更多