我有多个模型,多个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方式。
答案 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
)