4

クライアント向けのバックエンドとして django admin を使用しているため、ユーザーフレンドリーにする必要があります。栄養データを表す多数の DecimalFields を持つモデルがあります。

フィールドはすべて次のようになります。

g_carbs = DecimalField(max_digits=13, decimal_places = 8, null=True, blank=True)

フィールドが空白のままの場合、またはゼロ以外の値が指定された場合、管理フォームは見た目も機能も優れています。たとえば、10.5 のような空白でもゼロでもない値の場合、 のように表示されますが10.50000000、これで問題ありません。

問題は、値が 0 の場合、フォーム フィールドに表示さ0E-8 れることです。これは、技術的には正しいものの、ほとんどの場合科学者やエンジニアではなく、E 表記法に慣れていない私のクライアントにとっては適切ではありません。

カスタム フォームやカスタムの管理者用トリックは使用していません。そのモデルのdjango管理者によって自動レンダリングされるものです。これについてdjangoにチケットを送信することを検討していますが、それまでの間、カスタムフォームまたはこの問題を解決するために何かできることはありますか?

4

3 に答える 3

4

これが私のために働いたものです(これまでのところ)。これにより、E 表記が防止され、小数点以下の末尾の 0 が削除されます。

class NonscientificDecimalField(DecimalField):
    """ Prevents values from being displayed with E notation, with trailing 0's 
        after the decimal place  truncated. (This causes precision to be lost in 
        many cases, but is more user friendly and consistent for non-scientist 
        users)
    """
    def value_from_object(self, obj):
        def remove_exponent(val):
            """Remove exponent and trailing zeros.
               >>> remove_exponent(Decimal('5E+3'))
               Decimal('5000')
            """
            context = decimal.Context(prec=self.max_digits)
            return val.quantize(decimal.Decimal(1), context=context) if val == val.to_integral() else val.normalize(context)

        val = super(NonscientificDecimalField, self).value_from_object(obj)
        if isinstance(val, decimal.Decimal):
            return remove_exponent(val)
于 2012-11-03T15:50:55.050 に答える
1

簡単な方法の 1 つは、DecimalField をサブクラス化し、そのフォーマットを変更することです。

from django.db.models.fields import DecimalField

class NonscientificDecimalField(DecimalField):
    def format_number(self, value):
        """
        Overrides DecimalField's usual format_number by making sure 
        that the result is never in exponential notation for zero.
        """
        if value == 0:
            return "0.00000000"
        else:
            return super(DecimalField, self).format_number(value)

ところで、これを Django のバグとして提出するべきではありません。これは Python の 10 進数の動作であり、Django とはほとんど関係がありません。シェルを開いて試してみるstr(Decimal("0.00000000"))と、Decimal('0E-8').

10.50000000として表示したい場合は、小数10.5を呼び出すことができます。normalizeこれで問題も解決します0E-8

import decimal
from django.db.models.fields import DecimalField

class NonscientificDecimalField(DecimalField):
    def format_number(self, value):
        """
        Overrides DecimalField's usual format_number to remove trailing zeroes.
        """
        if isinstance(value, decimal.Decimal):
            context = decimal.Context(prec=self.max_digits)
            value = value.normalize(context=context)
        return super(DecimalField, self).format_number(value)
于 2012-10-31T18:53:20.533 に答える