Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Added support for timezones (new in Django 1.4).

From Django 1.4 onwards, settings.USE_TZ = True is the default for new
projects. It makes sense to run the tests with this setting.

Warnings related to time zones support are turned into exceptions to
make debugging easier and prevent regressions in this area.
  • Loading branch information...
commit 06f57f7c50461f861699aa62b41c9bdab4749980 1 parent 96003df
@aaugustin aaugustin authored
View
4 cms/models/pagemodel.py
@@ -6,9 +6,9 @@
from cms.models.pluginmodel import CMSPlugin
from cms.publisher.errors import MpttPublisherCantPublish
from cms.utils import i18n, urlutils, page as page_utils
+from cms.utils import timezone
from cms.utils.copy_plugins import copy_plugins_to
from cms.utils.helpers import reversion_register
-from datetime import datetime
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
@@ -344,7 +344,7 @@ def save(self, no_signals=False, change_state=True, commit=True,
# if the page is published we set the publish date if not set yet.
if self.publication_date is None and self.published:
- self.publication_date = datetime.now()
+ self.publication_date = timezone.now()
if self.reverse_id == "":
self.reverse_id = None
View
5 cms/models/pluginmodel.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
import os
import warnings
-from datetime import datetime, date
+from datetime import date
from django.conf import settings
from django.core.exceptions import ValidationError, ObjectDoesNotExist
@@ -14,6 +14,7 @@
from cms.models.placeholdermodel import Placeholder
from cms.plugin_rendering import PluginContext, render_plugin
from cms.utils.helpers import reversion_register
+from cms.utils import timezone
from mptt.models import MPTTModel, MPTTModelBase
@@ -81,7 +82,7 @@ class CMSPlugin(MPTTModel):
position = models.PositiveSmallIntegerField(_("position"), blank=True, null=True, editable=False)
language = models.CharField(_("language"), max_length=15, blank=False, db_index=True, editable=False)
plugin_type = models.CharField(_("plugin_name"), max_length=50, db_index=True, editable=False)
- creation_date = models.DateTimeField(_("creation date"), editable=False, default=datetime.now)
+ creation_date = models.DateTimeField(_("creation date"), editable=False, default=timezone.now)
changed_date = models.DateTimeField(auto_now=True)
level = models.PositiveIntegerField(db_index=True, editable=False)
lft = models.PositiveIntegerField(db_index=True, editable=False)
View
7 cms/models/query.py
@@ -5,6 +5,7 @@
from cms.publisher.query import PublisherQuerySet
from django.conf import settings
from cms.exceptions import NoHomeFound
+from cms.utils import timezone
#from cms.utils.urlutils import levelize_path
@@ -53,13 +54,13 @@ def published(self, site=None):
if settings.CMS_SHOW_START_DATE:
pub = pub.filter(
- Q(publication_date__lt=datetime.now()) |
+ Q(publication_date__lt=timezone.now()) |
Q(publication_date__isnull=True)
)
if settings.CMS_SHOW_END_DATE:
pub = pub.filter(
- Q(publication_end_date__gte=datetime.now()) |
+ Q(publication_end_date__gte=timezone.now()) |
Q(publication_end_date__isnull=True)
)
@@ -67,7 +68,7 @@ def published(self, site=None):
def expired(self):
return self.on_site().filter(
- publication_end_date__lte=datetime.now())
+ publication_end_date__lte=timezone.now())
# - seems this is not used anymore...
# def get_pages_with_application(self, path, language):
View
4 cms/models/titlemodels.py
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-
-from datetime import datetime
from django.db import models
from django.utils.translation import ugettext_lazy as _
from cms.models.managers import TitleManager
from cms.models.pagemodel import Page
from cms.utils.helpers import reversion_register
+from cms.utils import timezone
class Title(models.Model):
@@ -20,7 +20,7 @@ class Title(models.Model):
meta_keywords = models.CharField(_("keywords"), max_length=255, blank=True, null=True)
page_title = models.CharField(_("title"), max_length=255, blank=True, null=True, help_text=_("overwrite the title (html title tag)"))
page = models.ForeignKey(Page, verbose_name=_("page"), related_name="title_set")
- creation_date = models.DateTimeField(_("creation date"), editable=False, default=datetime.now)
+ creation_date = models.DateTimeField(_("creation date"), editable=False, default=timezone.now)
objects = TitleManager()
View
7 cms/tests/page.py
@@ -20,6 +20,7 @@
from cms.test_utils.util.context_managers import (LanguageOverride,
SettingsOverride)
from cms.utils.page_resolver import get_page_from_request, is_valid_url
+from cms.utils import timezone
from django.conf import settings
from django.contrib.sites.models import Site
from django.core.exceptions import ValidationError
@@ -367,7 +368,7 @@ def test_sitemap_login_required_pages(self):
self.assertEqual(CMSSitemap().items().count(),0)
def test_sitemap_includes_last_modification_date(self):
- one_day_ago = datetime.datetime.now() - datetime.timedelta(days=1)
+ one_day_ago = timezone.now() - datetime.timedelta(days=1)
page = create_page("page", "nav_playground.html", "en", published=True, publication_date=one_day_ago)
page.creation_date = one_day_ago
page.save()
@@ -377,7 +378,7 @@ def test_sitemap_includes_last_modification_date(self):
self.assertTrue(actual_last_modification_time > one_day_ago)
def test_sitemap_uses_publication_date_when_later_than_modification(self):
- now = datetime.datetime.now()
+ now = timezone.now()
one_day_ago = now - datetime.timedelta(days=1)
page = create_page("page", "nav_playground.html", "en", published=True, publication_date=now)
page.creation_date = one_day_ago
@@ -552,7 +553,7 @@ def test_page_already_expired(self):
Test that a page which has a end date in the past gives a 404, not a
500.
"""
- yesterday = datetime.date.today() - datetime.timedelta(days=1)
+ yesterday = timezone.now() - datetime.timedelta(days=1)
with SettingsOverride(CMS_MODERATOR=False, CMS_PERMISSION=False):
page = create_page('page', 'nav_playground.html', 'en',
publication_end_date=yesterday, published=True)
View
3  cms/tests/plugins.py
@@ -24,6 +24,7 @@
from cms.sitemaps.cms_sitemap import CMSSitemap
from cms.test_utils.util.context_managers import SettingsOverride
from cms.utils.copy_plugins import copy_plugins_to
+from cms.utils import timezone
from django.conf import settings
from django.contrib import admin
from django.contrib.auth.models import User
@@ -653,7 +654,7 @@ def test_empty_plugin_is_ignored(self):
self.assertFalse(len(placeholder._en_plugins_cache))
def test_editing_plugin_changes_page_modification_time_in_sitemap(self):
- now = datetime.datetime.now()
+ now = timezone.now()
one_day_ago = now - datetime.timedelta(days=1)
page = create_page("page", "nav_playground.html", "en", published=True, publication_date=now)
page.creation_date = one_day_ago
View
3  cms/utils/moderator.py
@@ -3,6 +3,7 @@
from django.utils.translation import ugettext as _
from django.conf import settings
from cms.models import Page, PageModeratorState, PageModerator, CMSPlugin, Title
+from cms.utils import timezone
I_APPROVE = 100 # current user should approve page
I_APPROVE_DELETE = 200
@@ -53,7 +54,7 @@ def update_moderation_message(page, message):
from cms.utils.permissions import get_current_user
user = get_current_user()
- created = datetime.datetime.now() - datetime.timedelta(seconds=UPDATE_TOLERANCE)
+ created = timezone.now() - datetime.timedelta(seconds=UPDATE_TOLERANCE)
try:
state = page.pagemoderatorstate_set.filter(user=user, created__gt=created).order_by('-created')[0]
# just state without message!!
View
47 cms/utils/timezone.py
@@ -0,0 +1,47 @@
+# This file is a partial copy of django.utils.timezone as of Django 1.4.
+# It must be removed as soon as django-cms drops support for Django 1.3.
+# All imports of cms.utils.timezone must be replaced by django.utils.timezone.
+
+from datetime import datetime, timedelta, tzinfo
+from threading import local
+
+try:
+ import pytz
+except ImportError:
+ pytz = None
+
+from django.conf import settings
+
+ZERO = timedelta(0)
+
+class UTC(tzinfo):
+ """
+ UTC implementation taken from Python's docs.
+
+ Used only when pytz isn't available.
+ """
+
+ def __repr__(self):
+ return "<UTC>"
+
+ def utcoffset(self, dt):
+ return ZERO
+
+ def tzname(self, dt):
+ return "UTC"
+
+ def dst(self, dt):
+ return ZERO
+
+utc = pytz.utc if pytz else UTC()
+"""UTC time zone as a tzinfo instance."""
+
+def now():
+ """
+ Returns an aware or naive datetime.datetime, depending on settings.USE_TZ.
+ """
+ if settings.USE_TZ:
+ # timeit shows that datetime.now(tz=utc) is 24% slower
+ return datetime.utcnow().replace(tzinfo=utc)
+ else:
+ return datetime.now()
View
9 runtests.py
@@ -2,8 +2,10 @@
from __future__ import with_statement
from cms.test_utils.cli import configure
from cms.test_utils.tmpdir import temp_dir
+from django import VERSION
import argparse
import sys
+import warnings
def main(test_runner='cms.test_utils.runners.NormalTestRunner', junit_output_dir='.',
@@ -12,9 +14,14 @@ def main(test_runner='cms.test_utils.runners.NormalTestRunner', junit_output_dir
test_labels = ['cms']
with temp_dir() as STATIC_ROOT:
with temp_dir() as MEDIA_ROOT:
+ # Test with time zone support enabled when it's available
+ use_tz = VERSION[:2] >= (1, 4)
+ warnings.filterwarnings(
+ 'error', r"DateTimeField received a naive datetime",
+ RuntimeWarning, r'django\.db\.models\.fields')
configure(TEST_RUNNER=test_runner, JUNIT_OUTPUT_DIR=junit_output_dir,
TIME_TESTS=time_tests, ROOT_URLCONF='cms.test_utils.project.urls',
- STATIC_ROOT=STATIC_ROOT, MEDIA_ROOT=MEDIA_ROOT)
+ STATIC_ROOT=STATIC_ROOT, MEDIA_ROOT=MEDIA_ROOT, USE_TZ=use_tz)
from django.conf import settings
from django.test.utils import get_runner
TestRunner = get_runner(settings)
Please sign in to comment.
Something went wrong with that request. Please try again.