DecimalField now stores as float not string (#289)
This commit is contained in:
@@ -260,30 +260,57 @@ class FloatField(BaseField):
|
||||
class DecimalField(BaseField):
|
||||
"""A fixed-point decimal number field.
|
||||
|
||||
.. versionchanged:: 0.8
|
||||
.. versionadded:: 0.3
|
||||
"""
|
||||
|
||||
def __init__(self, min_value=None, max_value=None, **kwargs):
|
||||
self.min_value, self.max_value = min_value, max_value
|
||||
def __init__(self, min_value=None, max_value=None, force_string=False,
|
||||
precision=2, rounding=decimal.ROUND_HALF_UP, **kwargs):
|
||||
"""
|
||||
:param min_value: Validation rule for the minimum acceptable value.
|
||||
:param max_value: Validation rule for the maximum acceptable value.
|
||||
:param force_string: Store as a string.
|
||||
:param precision: Number of decimal places to store.
|
||||
:param rounding: The rounding rule from the python decimal libary:
|
||||
|
||||
- decimial.ROUND_CEILING (towards Infinity)
|
||||
- decimial.ROUND_DOWN (towards zero)
|
||||
- decimial.ROUND_FLOOR (towards -Infinity)
|
||||
- decimial.ROUND_HALF_DOWN (to nearest with ties going towards zero)
|
||||
- decimial.ROUND_HALF_EVEN (to nearest with ties going to nearest even integer)
|
||||
- decimial.ROUND_HALF_UP (to nearest with ties going away from zero)
|
||||
- decimial.ROUND_UP (away from zero)
|
||||
- decimial.ROUND_05UP (away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise towards zero)
|
||||
|
||||
Defaults to: ``decimal.ROUND_HALF_UP``
|
||||
|
||||
"""
|
||||
self.min_value = min_value
|
||||
self.max_value = max_value
|
||||
self.force_string = force_string
|
||||
self.precision = decimal.Decimal(".%s" % ("0" * precision))
|
||||
self.rounding = rounding
|
||||
|
||||
super(DecimalField, self).__init__(**kwargs)
|
||||
|
||||
def to_python(self, value):
|
||||
original_value = value
|
||||
if not isinstance(value, basestring):
|
||||
value = unicode(value)
|
||||
try:
|
||||
value = decimal.Decimal(value)
|
||||
except ValueError:
|
||||
return original_value
|
||||
return value
|
||||
if value is None:
|
||||
return value
|
||||
|
||||
return decimal.Decimal(value).quantize(self.precision,
|
||||
rounding=self.rounding)
|
||||
|
||||
def to_mongo(self, value):
|
||||
return unicode(value)
|
||||
if value is None:
|
||||
return value
|
||||
if self.force_string:
|
||||
return unicode(value)
|
||||
return float(self.to_python(value))
|
||||
|
||||
def validate(self, value):
|
||||
if not isinstance(value, decimal.Decimal):
|
||||
if not isinstance(value, basestring):
|
||||
value = str(value)
|
||||
value = unicode(value)
|
||||
try:
|
||||
value = decimal.Decimal(value)
|
||||
except Exception, exc:
|
||||
@@ -295,6 +322,9 @@ class DecimalField(BaseField):
|
||||
if self.max_value is not None and value > self.max_value:
|
||||
self.error('Decimal value is too large')
|
||||
|
||||
def prepare_query_value(self, op, value):
|
||||
return self.to_mongo(value)
|
||||
|
||||
|
||||
class BooleanField(BaseField):
|
||||
"""A boolean field type.
|
||||
|
||||
@@ -9,7 +9,7 @@ __all__ = ('query', 'update')
|
||||
|
||||
|
||||
COMPARISON_OPERATORS = ('ne', 'gt', 'gte', 'lt', 'lte', 'in', 'nin', 'mod',
|
||||
'all', 'size', 'exists', 'not')
|
||||
'all', 'size', 'exists', 'not')
|
||||
GEO_OPERATORS = ('within_distance', 'within_spherical_distance',
|
||||
'within_box', 'within_polygon', 'near', 'near_sphere',
|
||||
'max_distance')
|
||||
@@ -74,7 +74,7 @@ def query(_doc_cls=None, _field_operation=False, **query):
|
||||
if op in singular_ops:
|
||||
if isinstance(field, basestring):
|
||||
if (op in STRING_OPERATORS and
|
||||
isinstance(value, basestring)):
|
||||
isinstance(value, basestring)):
|
||||
StringField = _import_class('StringField')
|
||||
value = StringField.prepare_query_value(op, value)
|
||||
else:
|
||||
@@ -144,7 +144,7 @@ def query(_doc_cls=None, _field_operation=False, **query):
|
||||
merge_query[k].append(mongo_query[k])
|
||||
del mongo_query[k]
|
||||
if isinstance(v, list):
|
||||
value = [{k:val} for val in v]
|
||||
value = [{k: val} for val in v]
|
||||
if '$and' in mongo_query.keys():
|
||||
mongo_query['$and'].append(value)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user