Restrict django FloatField to 2 decimal places

50,039

Solution 1

If you are only concerned with how your FloatField appears in forms, you can use the template filter floatformat.

From the Django Docs:

If used with a numeric integer argument, floatformat rounds a number to that many decimal places.

For example, if value = 34.23234, then in your template:

{{ value|floatformat:2 }}  # outputs 34.23

Solution 2

If you'd like to actually ensure that your model always gets saved with only two decimal places, rather than just changing the presentation of the model in a template, a custom save method on your model will work great. The example model below shows how.

class MyDataModel(models.Model):
    my_float = models.FloatField()

    def save(self, *args, **kwargs):
        self.my_float = round(self.my_float, 2)
        super(MyDataModel, self).save(*args, **kwargs)

Now every time you save your model you will guarantee that the field will only be populated with a float of two decimal places. This can be generalized to rounding to any number of decimal places.

Solution 3

Since Django 1.8+ you can use a custom validator for FloatField/or any ModelFields:

def validate_decimals(value):
    try:
        return round(float(value), 2)
    except:
        raise ValidationError(
            _('%(value)s is not an integer or a float  number'),
            params={'value': value},
        )

...and in your model you can apply it like this:

from django.db import models

class MyModel(models.Model):
    even_field = models.FloatField(validators=[validate_decimals])
Share:
50,039

Related videos on Youtube

Aidan Doherty
Author by

Aidan Doherty

Junior programmer for Level Up

Updated on June 04, 2020

Comments

  • Aidan Doherty
    Aidan Doherty almost 4 years

    I am looking for a way to limit the FloatField in Django to 2 decimal places has anyone got a clue of how this could be done without having to use a DecimalField.

    I tried decimal_places=2but this was just giving me a migration error within the float field so i am thinking this method must only work within DecimalFields.

    • alecxe
      alecxe almost 10 years
      Why don't you want to use a DecimalField?
    • ajknzhol
      ajknzhol almost 10 years
      did u try this models.FloatField(default=to_some_value)
    • Aidan Doherty
      Aidan Doherty almost 10 years
      because the decimal fields add the increment and decrement arrows within the input box and i dont want that appear i have not tried the default method but will look it up and see if its right for what i need.
    • alecxe
      alecxe almost 10 years
      @AidanDoherty so, the reason is just how does it appear on the form? You know - you can change it by setting up a different widget for the field.
    • Aidan Doherty
      Aidan Doherty almost 10 years
      @alecxe So i would do that by overwriting the Decimal Field widget to changes its type value then?.
    • Rod Xavier
      Rod Xavier almost 10 years
      You can refer to this link for more info about Django widgets. docs.djangoproject.com/en/dev/ref/forms/widgets
  • Aidan Doherty
    Aidan Doherty almost 10 years
    Thats good but isn't completely what i am looking for but i am sure this will come in handy in the future projects thanks for your help.
  • Lal
    Lal almost 7 years
    This helps. I am using Postgres with Django FloatField(default=0.00) but its saving it as 0 by removing useless 0s in decimal places.. which make sense.. but i want to show consistent values 0.00 or 5.43 in template... {{ value|floatformat:2 }} did the trick
  • user1847
    user1847 over 6 years
    This will not work. Validators do not change the values that are being saved, they only validate that a value is acceptable. If the value is unacceptable an exception should be raised. This will not modify the value that is being saved.
  • user1847
    user1847 over 6 years
    See my answer below for an answer that will ensure a float field rounds to two decimal places.
  • user1847
    user1847 over 6 years
    See my answer for ensuring that your data field always rounds to two decimals at the database level.
  • Mohammed Shareef C
    Mohammed Shareef C over 3 years
    this save method won't be executed if you call the update method on a queryset.
  • Mohammed Shareef C
    Mohammed Shareef C over 3 years
    How to use this with a django ModelForm instance ?