DateTimeField now auto converts valid datetime isostrings into dates (#343)
This commit is contained in:
parent
f1b97fbc8b
commit
5447c6e947
@ -5,6 +5,8 @@ Changelog
|
||||
|
||||
Changes in 0.8.2
|
||||
================
|
||||
- DateTimeField now auto converts valid datetime isostrings into dates (#343)
|
||||
- DateTimeField now uses dateutil for parsing if available (#343)
|
||||
- Fixed Doc.objects(read_preference=X) not setting read preference (#352)
|
||||
- Django session ttl index expiry fixed (#329)
|
||||
- Fixed pickle.loads (#342)
|
||||
|
@ -7,6 +7,7 @@ import urllib2
|
||||
import uuid
|
||||
import warnings
|
||||
from operator import itemgetter
|
||||
|
||||
try:
|
||||
import dateutil
|
||||
except ImportError:
|
||||
@ -353,6 +354,11 @@ class BooleanField(BaseField):
|
||||
class DateTimeField(BaseField):
|
||||
"""A datetime field.
|
||||
|
||||
Uses the python-dateutil library if available alternatively use time.strptime
|
||||
to parse the dates. Note: python-dateutil's parser is fully featured and when
|
||||
installed you can utilise it to convert varing types of date formats into valid
|
||||
python datetime objects.
|
||||
|
||||
Note: Microseconds are rounded to the nearest millisecond.
|
||||
Pre UTC microsecond support is effecively broken.
|
||||
Use :class:`~mongoengine.fields.ComplexDateTimeField` if you
|
||||
@ -360,13 +366,11 @@ class DateTimeField(BaseField):
|
||||
"""
|
||||
|
||||
def validate(self, value):
|
||||
if not isinstance(value, (datetime.datetime, datetime.date)):
|
||||
new_value = self.to_mongo(value)
|
||||
if not isinstance(new_value, (datetime.datetime, datetime.date)):
|
||||
self.error(u'cannot parse date "%s"' % value)
|
||||
|
||||
def to_mongo(self, value):
|
||||
return self.prepare_query_value(None, value)
|
||||
|
||||
def prepare_query_value(self, op, value):
|
||||
if value is None:
|
||||
return value
|
||||
if isinstance(value, datetime.datetime):
|
||||
@ -376,10 +380,16 @@ class DateTimeField(BaseField):
|
||||
if callable(value):
|
||||
return value()
|
||||
|
||||
if not isinstance(value, basestring):
|
||||
return None
|
||||
|
||||
# Attempt to parse a datetime:
|
||||
if dateutil:
|
||||
return dateutil.parser.parse(value)
|
||||
# value = smart_str(value)
|
||||
try:
|
||||
return dateutil.parser.parse(value)
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
# split usecs, because they are not recognized by strptime.
|
||||
if '.' in value:
|
||||
try:
|
||||
@ -404,6 +414,9 @@ class DateTimeField(BaseField):
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
def prepare_query_value(self, op, value):
|
||||
return self.to_mongo(value)
|
||||
|
||||
|
||||
class ComplexDateTimeField(StringField):
|
||||
"""
|
||||
|
2
setup.py
2
setup.py
@ -57,7 +57,7 @@ if sys.version_info[0] == 3:
|
||||
extra_opts['packages'].append("tests")
|
||||
extra_opts['package_data'] = {"tests": ["fields/mongoengine.png", "fields/mongodb_leaf.png"]}
|
||||
else:
|
||||
extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django>=1.4.2', 'PIL', 'jinja2==2.6']
|
||||
extra_opts['tests_require'] = ['nose', 'coverage', 'blinker', 'django>=1.4.2', 'PIL', 'jinja2==2.6', 'python-dateutil==1.5']
|
||||
extra_opts['packages'] = find_packages(exclude=('tests',))
|
||||
|
||||
setup(name='mongoengine',
|
||||
|
@ -408,9 +408,16 @@ class FieldTest(unittest.TestCase):
|
||||
log.time = datetime.date.today()
|
||||
log.validate()
|
||||
|
||||
log.time = datetime.datetime.now().isoformat(' ')
|
||||
log.validate()
|
||||
|
||||
if dateutil:
|
||||
log.time = datetime.datetime.now().isoformat('T')
|
||||
log.validate()
|
||||
|
||||
log.time = -1
|
||||
self.assertRaises(ValidationError, log.validate)
|
||||
log.time = '1pm'
|
||||
log.time = 'ABC'
|
||||
self.assertRaises(ValidationError, log.validate)
|
||||
|
||||
def test_datetime_tz_aware_mark_as_changed(self):
|
||||
@ -497,6 +504,7 @@ class FieldTest(unittest.TestCase):
|
||||
d1 = datetime.datetime(1970, 01, 01, 00, 00, 01)
|
||||
log = LogEntry()
|
||||
log.date = d1
|
||||
log.validate()
|
||||
log.save()
|
||||
|
||||
for query in (d1, d1.isoformat(' ')):
|
||||
|
Loading…
x
Reference in New Issue
Block a user