Freezegun总是导致RuntimeWarning接收天真的日期时间

时间:2018-05-09 21:37:16

标签: django timezone freezegun

我正在使用一个可以暂停组织的测试用例。 目前,我正在使用freezegun来冻结固定时间,这是一个datetime.datetime对象tzinfo=pytz.UTC

在下面的测试中,您会看到self.fake_datetime的打印件,其中会返回tzaware日期时间:2000-01-01 00:00:00+00:00

当测试运行时,我会继续获得着名的RuntimeWarning

  

/usr/local/lib/python2.7/dist-packages/django/db/models/fields/ init .py:1447:RuntimeWarning:DateTimeField Organization.suspended收到一个天真的日期时间( 2000-01-01 00:00:00)时区支持处于活动状态。     RuntimeWarning)

import datetime
import pytz

from freezegun import freeze_time
# crop

class OrganizationSuspendTestCase(TestCase):

    def setUp(self):
        self.organization = OrganizationFactory()
        self.fake_datetime = datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=pytz.UTC)
        print self.fake_datetime

    def test_suspend_organization(self):
        """
        Case: An organization is being suspended with the suspend service.
        Expected: The organization is updated with the suspending datetime and the reason.
        """
        with freeze_time(self.fake_datetime):
            mc_organization.services.organization.suspend(organization=self.organization, reason="Did not pay the bill")

        self.assertEqual(self.organization.suspended, datetime.datetime(2000, 1, 1, 0, 0, 0))

我一直在玩freezegun timezone examples而没有成功删除运行时警告。

有关如何正确解决此问题的任何建议?我希望在没有Freezegun的情况下继续使用RuntimeWarning。抑制是一种选择,但我不愿意。

更新 - 基于answer of xyres

的解决方案

服务正在保存日期时区时区。旧情况评论和新情况是实际的代码。我在考虑很多mocking,并假设保存在service中的日期时间将使用freezegun中的时区感知日期时间对象来模拟测试用例 - 事实并非如此。< / p>

def suspend(organization, reason):
    """
    Suspend an organization with the given reason.
    :param mc_organization.models.Organization organization: The organization to suspend.
    :param string reason: The reason of the suspending.
    :return: None
    """
    # organization.suspended = datetime.datetime.now() (Old sitation)
    organization.suspended = timezone.now()  # timezone aware situation.
    organization.suspended_reason = reason
    organization.save()

1 个答案:

答案 0 :(得分:2)

好像和你一样trying to save an object with a timezone-naive datetime。要消除此警告,只需在应用程序的任何位置使用时区感知日期时间。

您可以使用django.utils.timezone 处的Django pytz模块,而不是自己使用timezone手动管理时区。它有一些快捷方法可用于将天真日期时间转换为识别日期时间。

使用此功能的一个优点是,如果您更改设置文件中的时区设置,它会自动选择新的时区,而使用pytz,您必须手动更新新的时区

from django.utils import timezone

fake_datetime = timezone.make_aware(timezone.datetime(2000, 1, 1, 0, 0, 0))