Aidan Doherty
Aidan Doherty

Reputation: 1072

Restrict django FloatField to 2 decimal places

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=2, but this just gave me a migration error within the float field. So, I am thinking this method must only work within DecimalFields.

Upvotes: 45

Views: 75885

Answers (3)

pcoronel
pcoronel

Reputation: 3971

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

Upvotes: 86

user1847
user1847

Reputation: 3799

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.

Upvotes: 24

Catalin
Catalin

Reputation: 135

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])

Upvotes: 2

Related Questions