Opened 4 years ago

Closed 3 years ago

#31487 closed New feature (fixed)

Add support for precision argument to Round

Reported by: Baptiste Mispelon Owned by: Nick Pope
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords: database function, round, precision, decimal places
Cc: pope1ni Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Django's Round function currently only supports rounding to the nearest integer. If you need to round to a more specific precision you need to roll out your own solution.

But as far as I can tell, all backends natively supported by Django support a second argument to Round:

In my project (postgres only) my work around was to declare my own custom function:

class Round(Func):
    function = 'ROUND'
    arity = 2

But having this built-in would be quite useful.

Change History (10)

comment:1 by Simon Charette, 4 years ago

Triage Stage: UnreviewedAccepted

comment:2 by Hasan Ramezani, 4 years ago

Owner: changed from nobody to Hasan Ramezani
Status: newassigned

comment:3 by Mariusz Felisiak, 4 years ago

Cc: pope1ni added

Please take into account that it was discussed in the original PR, and we decided to leave Round() without a precision because it can be unstable around 0.5.

in reply to:  3 comment:4 by Baptiste Mispelon, 4 years ago

Replying to felixxm:

Please take into account that it was discussed in the original PR, and we decided to leave Round() without a precision because it can be unstable around 0.5.

What does "unstable around 0.5" mean? I assume it has something to do with what Python call rounding modes [1] but if that's the case I don't understand why that wouldn't also apply to rounding to integers.

The comment you link doesn't have a lot of information and itself links to another comment about Spatialite which doesn't really clarify much.
Navigating the discussion on the PR is a bit hard but searching for the word "round" in the commit history of the PR I found https://github.com/django/django/pull/9622/commits/5acc1162a716c4ff6fcb0bca32840e11d6585c7e.
The warning added in that commit seems like it was not integrated into the final commit (I searched Django's history with git log -S "equally close" -- docs/ to try and find it) but I can't find a comment explaining the decision to remove it.

Edit
While searching for more information about rounding modes in different databases, I found a useful reference of different rounding modes and their results when applied to various inputs: https://docs.oracle.com/javase/7/docs/api/java/math/RoundingMode.html

[1] https://docs.python.org/3/library/decimal.html#rounding-modes

Last edited 4 years ago by Baptiste Mispelon (previous) (diff)

comment:5 by Mariusz Felisiak, 4 years ago

The comment you link doesn't have a lot of information and itself links to another comment about Spatialite which doesn't really clarify much.

Agreed, that's why I CC'ed Nick, maybe he remember rationales.

comment:6 by Hasan Ramezani, 3 years ago

Owner: Hasan Ramezani removed
Status: assignednew

comment:7 by Nick Pope, 3 years ago

Has patch: set
Keywords: database function round precision decimal places added
Owner: set to Nick Pope
Status: newassigned
Version: 3.0dev

For once, I can't remember exactly why we didn't do this, hence my opening of the duplicate ticket #32592 yesterday looking to fix exactly this issue.

I can think of a number of possible reasons based on the discussions and looking at the existing code:

  • Something to do with the rounding issue around 0.5. (I don't think this should stop us supporting the second argument. We already mention it in the documentation.)
  • Something to do with Round being a Transform which sets arity = 1. (This can be overridden back to None while still allowing the transform to work.)
  • Something to do with SpatiaLite. I'm not sure what that comment was about as SQLite and SpatialLite behave the same and the function is available in SQLite.
  • The SQLite version of ROUND() does not support negative precision values.

Anyway, here is a PR.

comment:8 by Mariusz Felisiak, 3 years ago

Patch needs improvement: set

comment:9 by Mariusz Felisiak, 3 years ago

Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:10 by Mariusz Felisiak <felisiak.mariusz@…>, 3 years ago

Resolution: fixed
Status: assignedclosed

In 2f13c476:

Fixed #31487 -- Added precision argument to Round().

Note: See TracTickets for help on using tickets.
Back to Top