3

I'm attempting to create a custom form field that works the same as float field for all intents and purposes, but that (by default) outputs the float value with no trailing zeros e.g. 33 rather than 33.0

I attempted to simply extend django.forms.FloatField like so:

class CustomFloatField(django.forms.FloatField):

    def to_python(self, value):
        """
        Returns the value without trailing zeros.
        """
        value = super(django.forms.FloatField, self).to_python(value)
        # code to strip trailing zeros
        return stripped_value

But this ended up with me getting validation errors. When I looked closer at the FloatField class I noticed that in its own to_python() method it calls super(IntegerField, self).to_python(value) which checks to ensure the value can be cast to an int, and it was here that my code seemed to trip up. This has left me thoroughly confused. How does FloatField work at all if it has to try and cast it's value to an int? :)

Most likely I'm barking entirely up the wrong tree here but if someone could point me in the right direction I'd be grateful.

PT114
  • 931
  • 3
  • 10
  • 18

1 Answers1

2

Your hunch is right - FloatField isn't really calling on the to_python method of IntegerField. To illustrate what's really going on,

class A(object):
    def __init__(self):
        print "A initialized"

    def to_python(self, value):
        print "A: to_python"
        return value

class B(A):
    def __init__(self):
        print "B initialized"

    def to_python(self, value):
        value = super(B, self).to_python(value)
        print "B: value = "
        print int(value)
        return int(value)

class C(B):
    def to_python(self, value):
        value = super(B, self).to_python(value)
        print "C: value = "
        print float(value)
        return float(value)

c = C()
c.to_python(5.5)

gives the output,

B initialized
A: to_python
C: value = 
5.5 

To put it in context, the line in FloatField's to_python:

value = super(IntegerField, self).to_python(value)

is really calling up to Field's to_python, which is simply,

def to_python(self, value):
    return value

before calling the rest of the code. This might help you further: Understanding Python super() with __init__() methods

Community
  • 1
  • 1
Kenny Shen
  • 4,773
  • 3
  • 21
  • 18