Cloud Artisans
Cloud Artisans

Reputation: 4136

Django best practice to round decimals: frontend or backend?

I have a fairly extensive Django site that deals with currency amounts that need to be displayed with 2 decimal places, but since there are mathematical operations performed on these amounts, behind the scenes, 4 place decimals are used. Some pages get these amounts via AJAX calls (as JSON) and other pages get them via the standard view => template variable passing. My models use models.DecimalField(max_digits=10, decimal_places=4, default=Decimal('0'))

The site is large enough now that I need to figure out a consistent way to handle this decimal rounding, but no matter which way I do it, it seems awkward. Here are the two ways I can think of, but each seems less than ideal.

  1. Frontend: views leave the decimals unchanged, with 4 places. Templates use the floatformat:2 filter and JS functions use .toFixed(2) for the conversion of incoming JSON data. Problem: need to handle the rounding in many places in template code and JS code.

  2. Backend: views round all decimals to 2 places and pass them as strings to the templates. Likewise, responses to incoming AJAX calls serialize all decimals to 2 places. Problem: views are now handling formatting instead of templates and special cases cannot be formatted differently in the template.

Is there a "proper, Djangonic" way of handling Decimal rounding?

Upvotes: 1

Views: 2114

Answers (1)

Evan Brumley
Evan Brumley

Reputation: 2468

Considering that this is purely a presentation issue, my instinct would be keep it in the templates. That said, the templates should be as dumb as possible, and you probably don't want to hard code your decimal place counts as magic numbers all over your templates.

I would probably do something like the following:

  • Don't process any decimal place stuff in your views, unless it's part of your calculation logic.
  • Write a custom template filter that formats your floats based on parameters defined in your settings.py
  • Write a custom JavaScript function that does the same
  • Use your new filter and function to manipulate decimals as they appear in templates and AJAX callbacks.

That way your keep all your presentation logic at the template level, but you still maintain DRY principles. It still means lots of edits to your templates and JavaScript, but I can't really think of any cleaner way to do it without getting into really hacky territory.

Upvotes: 2

Related Questions