Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Cannot convert float to Decimal. First convert the float to a string

Tags:

django

I have a model that automatically re sizes the image and save the original also when you upload a picture.

The problem is , when I save the image at the admin panel, I get this error

Cannot convert float to Decimal. First convert the float to a string

File "C:\o\mysite\fruit\models.py" in save
 61.         super(Pic, self).save(*args, **kwargs)
 File "C:\Python26\lib\decimal.py" in __new__
  652.                             "First convert the float to a string")

Exception Type: TypeError at /admin/fruit/pic/add/
Exception Value: Cannot convert float to Decimal.  First convert the float to a string

I just can't figure why do I get this error

My models.py

class Pic(models.Model):
    user = models.ForeignKey(User)
    image = models.ImageField(
        upload_to="image",
        blank=True
        )
    descrip = models.TextField()
    ratio = models.DecimalField(decimal_places=5,max_digits=10,default=0)

    def __unicode__(self):
        return self.descrip

    def original(self):
        width = self.image.width / float(self.ratio)
        height = self.image.height / float(self.ratio)

        result = "<img src='/media/{0}' height='{1}' width='{2}'>".format(
            self.image, height, width)

    return result

    def save(self, *args, **kwargs):       
        pw = self.image.width
        ph = self.image.height
        mw = 200
        mh = 200

        self.ratio = getWH(pw, ph, mw, mh, 'r')

        super(Pic, self).save(*args, **kwargs)

        if (pw > mw) or (ph > mh):
            filename = str(self.image.path)
            imageObj = img.open(filename)

            ratio = 1

            if (pw > mw):
                ratio = mw / float(pw)
                pw = mw
                ph = int(math.floor(float(ph)* ratio))
            if ( ph > mh):
                ratio = ratio * ( mh /float(ph))
                ph = mh
                pw = int(math.floor(float(ph)* ratio))

            width = getWH(pw, ph, mw, mh, 'w')
            height = getWH(pw, ph, mw, mh, 'h')

            imageObj = imageObj.resize((width, height),img.ANTIALIAS)
            imageObj.save(filename)



def getWH(pw, ph, mw, mh, result):
    ratio = 1

    if (pw > mw):
        ratio = mw / float(pw)
        pw = mw
        ph = int(math.floor(float(ph)* ratio))
    if ( ph > mh):
        ratio = ratio * ( mh /float(ph))
        ph = mh
        pw = int(math.floor(float(ph)* ratio))

    if result == 'w':
        return pw
    elif result == 'h':
        return ph
    else:
        return ratio
like image 759
donkeyboy72 Avatar asked Dec 02 '25 06:12

donkeyboy72


2 Answers

With Python 2.7+:

from decimal import Decimal
Decimal.from_float(234.234)

https://docs.python.org/2/library/decimal.html#decimal.Decimal.from_float

like image 111
Josh Avatar answered Dec 04 '25 00:12

Josh


As from official documentation 9.4.8. Decimal FAQ

Q. Why isn’t the float_to_decimal() routine included in the module?

A. There is some question about whether it is advisable to mix binary and decimal floating point. Also, its use requires some care to avoid the representation issues associated with binary floating point:

By the way you can find an answer in the given link:

def float_to_decimal(f):
    "Convert a floating point number to a Decimal with no loss of information"
    n, d = f.as_integer_ratio()
    numerator, denominator = Decimal(n), Decimal(d)
    ctx = Context(prec=60)
    result = ctx.divide(numerator, denominator)
    while ctx.flags[Inexact]:
        ctx.flags[Inexact] = False
        ctx.prec *= 2
        result = ctx.divide(numerator, denominator)
    return result

And also this feature already included in python 2.7.

like image 30
emcpow2 Avatar answered Dec 03 '25 23:12

emcpow2



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!