diff --git a/docs/changelog.rst b/docs/changelog.rst index 352d0c77..f934f5e0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -23,6 +23,7 @@ Changes in 0.8.X - Dynamic fields are now validated on save (#153) (#154) - Added support for multiple slices and made slicing chainable. (#170) (#190) (#191) - Fixed GridFSProxy __getattr__ behaviour (#196) +- Fix Django timezone support (#151) Changes in 0.7.9 ================ diff --git a/mongoengine/django/auth.py b/mongoengine/django/auth.py index 1685f6f0..6cee9c0a 100644 --- a/mongoengine/django/auth.py +++ b/mongoengine/django/auth.py @@ -1,5 +1,3 @@ -import datetime - from mongoengine import * from django.utils.encoding import smart_str @@ -33,6 +31,7 @@ except ImportError: hash = get_hexdigest(algo, salt, raw_password) return '%s$%s$%s' % (algo, salt, hash) +from .utils import datetime_now REDIRECT_FIELD_NAME = 'next' @@ -62,9 +61,9 @@ class User(Document): is_superuser = BooleanField(default=False, verbose_name=_('superuser status'), help_text=_("Designates that this user has all permissions without explicitly assigning them.")) - last_login = DateTimeField(default=datetime.datetime.now, + last_login = DateTimeField(default=datetime_now, verbose_name=_('last login')) - date_joined = DateTimeField(default=datetime.datetime.now, + date_joined = DateTimeField(default=datetime_now, verbose_name=_('date joined')) meta = { @@ -130,7 +129,7 @@ class User(Document): """Create (and save) a new user with the given username, password and email address. """ - now = datetime.datetime.now() + now = datetime_now() # Normalize the address by lowercasing the domain part of the email # address. diff --git a/mongoengine/django/sessions.py b/mongoengine/django/sessions.py index 810b6265..85ca25a0 100644 --- a/mongoengine/django/sessions.py +++ b/mongoengine/django/sessions.py @@ -1,5 +1,3 @@ -from datetime import datetime - from django.conf import settings from django.contrib.sessions.backends.base import SessionBase, CreateError from django.core.exceptions import SuspiciousOperation @@ -10,6 +8,8 @@ from mongoengine import fields from mongoengine.queryset import OperationError from mongoengine.connection import DEFAULT_CONNECTION_NAME +from .utils import datetime_now + MONGOENGINE_SESSION_DB_ALIAS = getattr( settings, 'MONGOENGINE_SESSION_DB_ALIAS', @@ -43,7 +43,7 @@ class SessionStore(SessionBase): def load(self): try: s = MongoSession.objects(session_key=self.session_key, - expire_date__gt=datetime.now())[0] + expire_date__gt=datetime_now)[0] if MONGOENGINE_SESSION_DATA_ENCODE: return self.decode(force_unicode(s.session_data)) else: diff --git a/mongoengine/django/utils.py b/mongoengine/django/utils.py new file mode 100644 index 00000000..d3ef8a4b --- /dev/null +++ b/mongoengine/django/utils.py @@ -0,0 +1,6 @@ +try: + # django >= 1.4 + from django.utils.timezone import now as datetime_now +except ImportError: + from datetime import datetime + datetime_now = datetime.now diff --git a/tests/test_django.py b/tests/test_django.py index 398fd3e0..3b0b04f8 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -12,7 +12,7 @@ try: from django.conf import settings from django.core.paginator import Paginator - settings.configure() + settings.configure(USE_TZ=True) from django.contrib.sessions.tests import SessionTestsMixin from mongoengine.django.sessions import SessionStore, MongoSession @@ -24,6 +24,37 @@ except Exception, err: raise err +from datetime import tzinfo, timedelta +ZERO = timedelta(0) + +class FixedOffset(tzinfo): + """Fixed offset in minutes east from UTC.""" + + def __init__(self, offset, name): + self.__offset = timedelta(minutes = offset) + self.__name = name + + def utcoffset(self, dt): + return self.__offset + + def tzname(self, dt): + return self.__name + + def dst(self, dt): + return ZERO + + +def activate_timezone(tz): + """Activate Django timezone support if it is available. + """ + try: + from django.utils import timezone + timezone.deactivate() + timezone.activate(tz) + except ImportError: + pass + + class QuerySetTest(unittest.TestCase): def setUp(self): @@ -120,3 +151,15 @@ class MongoDBSessionTest(SessionTestsMixin, unittest.TestCase): session['test'] = True session.save() self.assertTrue('test' in session) + + def test_session_expiration_tz(self): + activate_timezone(FixedOffset(60, 'UTC+1')) + # create and save new session + session = SessionStore() + session.set_expiry(600) # expire in 600 seconds + session['test_expire'] = True + session.save() + # reload session with key + key = session.session_key + session = SessionStore(key) + self.assertTrue('test_expire' in session, 'Session has expired before it is expected')