[Django]-Django custom form field change value in render and submit

3๐Ÿ‘

I had a similar problem displaying price fields that are internally stored as integers. This is what I learned:

You could overwrite the bounddata method in your field to return the initial rather than the entered data. The result of bound data still passes through prepare_value later, so you could implement this the same way you did before:

class MeterToKmField(forms.FloatField):
    def bound_data(self, data, initial):
        return initial

    def prepare_value(self,value):
        #...same as before, just divide by 1000

However this might not be what you want, as changes made by the user might be lost. My preferred solution therefore is based on the fact that the bound value in prepare_value is unicode and the unbound one is an integer. So you could do something like:

class MeterToKmField(forms.FloatField):
    def prepare_value(self, value):
        #python 2.x ,use str instead of basestring for python 3.x
        if isinstance(value, basestring):
            #in case of bound data, is already divided by 100
            return value
        else:
            #raw data
            return float(value)/ 1000

    #don't overwrite bound_data in this case
๐Ÿ‘คSara

0๐Ÿ‘

From looking at how date fields are implemented, it looks like the best way to do this is with both a custom field (so you can do the to_python customization) and a custom widget โ€“ one that implements _format_value.

So something like:

class KmInput(NumberInput):
    def _format_value(self, value):
        return str(value / 1000)

And then the form as above.

๐Ÿ‘คPeter DeGlopper

Leave a comment