Opened 6 years ago
Closed 5 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:
- Postgres: https://www.postgresql.org/docs/12/functions-math.html#FUNCTIONS-MATH-FUNC-TABLE
- Sqlite: https://sqlite.org/lang_corefunc.html#round
- MySQL: https://dev.mysql.com/doc/refman/8.0/en/mathematical-functions.html#function_round
- Oracle: https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions135.htm
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 , 6 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 6 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
follow-up: 4 comment:3 by , 6 years ago
| Cc: | added |
|---|
comment:4 by , 6 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 around0.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.
[1] https://docs.python.org/3/library/decimal.html#rounding-modes
comment:5 by , 6 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 , 5 years ago
| Owner: | removed |
|---|---|
| Status: | assigned → new |
comment:7 by , 5 years ago
| Has patch: | set |
|---|---|
| Keywords: | database function round precision decimal places added |
| Owner: | set to |
| Status: | new → assigned |
| Version: | 3.0 → dev |
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
Roundbeing aTransformwhich setsarity = 1. (This can be overridden back toNonewhile 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 , 5 years ago
| Patch needs improvement: | set |
|---|
comment:9 by , 5 years ago
| Patch needs improvement: | unset |
|---|---|
| Triage Stage: | Accepted → Ready for checkin |
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 around0.5.