'Django Decimal field with value Decimal(0.00) is displayed as 0E-10 in the Django Admin Inline
Django 2.2. Model Definition.
class BlockPeriod(BaseModel):
price = models.DecimalField(max_digits=20, decimal_places=10)
margin = models.DecimalField(max_digits=20, decimal_places=10)
If the user saves margin or price as "0" it would be displayed as "OE-10" on the next page load.
Screenshot is from DjangoAdmin.
I want to display 0 or 0.00 instead of OE-10 in margin and price fields.
Thanks
Solution 1:[1]
If you only want to display 2 places, you can simply set decimal_places to 2.
class BlockPeriod(BaseModel):
price = models.DecimalField(max_digits=20, decimal_places=2)
margin = models.DecimalField(max_digits=20, decimal_places=2)
You can also consider using a FloatField which leads to 0.0
as representation for 0.
float_value = models.FloatField()
Solution 2:[2]
The way out of it was adding form fields price
and margin
with decimal places set to 6. For any number higher Django renders inline fields with html step "1e-7","1e-8", "1e-9"... I wanted to keep 10 decimal places on DB level.
Solution 3:[3]
I solved this by creating a custom admin form widget that replaces 0E-10 with 0 using JavaScript. Here is the Django part:
from django import forms
from django.contrib import admin
class BlockPeriod(BaseModel):
price = models.DecimalField(max_digits=20, decimal_places=10)
margin = models.DecimalField(max_digits=20, decimal_places=10)
class DecimalWidget(forms.widgets.NumberInput):
class Media:
js = ('js/decimal_widget.js', )
class BlockPeriodAdminForm(forms.ModelForm):
class Meta:
widget = DecimalWidget(attrs={'class': 'decimal-widget'})
widgets = {'price': widget, 'margin': widget}
fields = '__all__'
class BlockPeriodAdmin(admin.ModelAdmin):
form = BlockPeriodAdminForm
admin.site.register(BlockPeriod, BlockPeriodAdmin)
Then somewhere under static/js/decimal_widget.js
(your file location may be different) you would have this JavaScript:
function convertDecimalValues() {
$('input.decimal-widget').each(function() {
if (this.value == '0E-10') { this.value = 0; }
});
}
$(document).ready(function() {
convertDecimalValues();
});
I will be the first to admit that this feels like an overkill, and there should be an easier way to do this. But this does the trick.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Sören |
Solution 2 | Yuri Kots |
Solution 3 | Sergei Krupenin |