简体   繁体   中英

django how to use Choices for a Model DecimalField

i need to have a field to store values in range of (-20 to 20 with step 0.25) and the values should be displayed like (1.50, 3.00, 5.25), so i thought i should use decimal instead of float an after some searching i have used this function to generate the required range:

def decimal_range(A, B, X):
"""
function to generate decimal floating numbers from start(A), to end(B), by step(X)
"""
getcontext().prec = 5
while A < B:
    yield float(A)
    A += Decimal(X)

and generated the filed choices like so.

S_CHOICES = tuple(tuple([i, f"{i:.2f}"]) for i in decimal_range(-20, 20.25, 0.25))

the result tuple is

((-20.0, '-20.00'), (-19.75, '-19.75'), (-19.5, '-19.50'), (-19.25, '-19.25'), (-19.0, '-19.00'), ...)

the model field is

arrs = models.DecimalField(max_digits=4, decimal_places=2, choices=S_CHOICES, null=True, blank=True, default=None)

and when looking inside the db.sqlite3 file i see some different values like (-20 instead of -20.0) .

also when checking from python shell for field value it is like Decimal('15.00'), Decimal('4.50')

in the end if i submitted a form with this field to value like 7.50 or 7.00 it is saved and retrieved correctly, but when trying to update this form the field value is going to be empty but if the value where like 1.75 or -13.75 it works without any issue.

some one please advise...

i have found the right way to have choices for the models.DecimalField after some try & error, so i thought this might help someone else.

the way to assign to a decimal field is either by decimal.Decimal object or a string – not a Python float.

so i have adjusted the choices tuple to:

from decimal import Decimal
    
S_CHOICES = tuple(tuple([Decimal(f"{i:.2f}"), f"{i:.2f}"]) for i in decimal_range(-20, 20.25, 0.25))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM