在django admin中显示带货币的DecimalField

时间:2013-09-12 08:56:18

标签: python django django-admin decimal currency-formatting

我有多个模型,多个DecimalField代表金钱,比如100.34欧元。

我的目标是在管理列表视图中显示货币,如此图片所示

http://i.imgur.com/XKEQFp9.png

然而,我无法找到办法为每个金钱领域做到这一点。

我尝试创建一个自定义MoneyField,继承自DecimalField并改变 unicode 表示,但它不起作用。

我也试过https://github.com/jakewins/django-money,但我没有运气。

我调查了django admin的源代码,我终于找到了问题:

在display_for_field函数的django.admin.contrib.admin.util.py中,它检查该值是否为DecimalField的实例。如果是这种情况,则会将其显示为十进制数字。

elif isinstance(field, models.DecimalField):
    return formats.number_format(value, field.decimal_places) 

这很有意义,但它阻止我在管理员中显示EUR符号/文字。

我该如何解决这个问题?

我知道我可以简单地为每个字段使用一种方法,将格式化的值显示为字符串,但我想知道是否存在DRYer方式。

3 个答案:

答案 0 :(得分:3)

要在管理列表中显示,您可以在ModelAdmin类中创建一个自定义函数,该函数将被调用以格式化每个值:

class MyModelAdmin(admin.ModelAdmin):
    list_display = ('formatted_amount', ...other fields...,)

    def formatted_amount(self, obj):
        # obj is the Model instance

        # If your locale is properly set, try also:
        # locale.currency(obj.amount, grouping=True)
        return '%.2f EUR' % obj.amount

答案 1 :(得分:1)

或者创建一个这样的类并从中继承

class ImprovedAdmin(admin.ModelAdmin):
    """Handles column formatting in list display"""
    def __init__(self, *args, **kwargs):
        def generate_formatter(name, str_format):
            formatter = lambda o: str_format%(getattr(o, name) or 0)
            formatter.short_description = name
            formatter.admin_order_field = name
            return formatter

        all_fields = []
        for f in self.list_display:
            if isinstance(f, basestring):
                all_fields.append(f)
            else:
                new_field_name = f[0]+'_formatted'
                setattr(self, new_field_name, generate_formatter(f[0], f[1]))
                all_fields.append(new_field_name)
        self.list_display = all_fields

        super(ImprovedAdmin, self).__init__(*args, **kwargs)


class MyModelAdmin(ImprovedAdmin):
    list_display = ('id', ('amount', '%.2f EUR'), ('interest', '%.2f %%'))

答案 2 :(得分:0)

0.12版本的django-money之前,Django管理员部分支持货币代理。

0.12版本(于2017年10月22日发布)以来,所有MoneyField个表示形式(包括Django的管理员)都可以使用特殊formatter进行配置。

import moneyed
from moneyed.localization import _FORMATTER
from decimal import ROUND_HALF_EVEN


BOB = moneyed.add_currency(
    code='BOB',
    numeric='068',
    name='Peso boliviano',
    countries=('BOLIVIA', )
)

# Currency Formatter will output 2.000,00 Bs.
_FORMATTER.add_sign_definition(
    'default',
    BOB,
    prefix=u'Bs. '
)

_FORMATTER.add_formatting_definition(
    'es_BO',
    group_size=3, group_separator=".", decimal_point=",",
    positive_sign="",  trailing_positive_sign="",
    negative_sign="-", trailing_negative_sign="",
    rounding_method=ROUND_HALF_EVEN
)