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.
|
||||
|
||||
Reference in New Issue
Block a user