2013-09-12 4 views
2

У меня есть несколько моделей с несколькими DecimalField, представляющими деньги, например 100.34 EUR.Отображение DecimalField с валютой в администраторе django

Моя цель состояла в том, чтобы вывести валюту в списке администратора, как показано в этом

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

изображение Однако я не мог найти способ сделать это для каждого денежного поля.

Я попытался создать пользовательский MoneyField, наследующий от DecimalField и сменивший unicode, но это не сработало.

Я также пробовал с https://github.com/jakewins/django-money, но мне не повезло.

я исследовал исходный код Джанго администратора, и я наконец-то нашел проблему:

В django.admin.contrib.admin.util.py в функции display_for_field она проверяет, если значение является экземпляром DecimalField. Если это так, он отображает его как десятичное число.

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

Это имеет смысл, но это мешает мне отображать символ/текст EUR в администраторе.

Как я могу решить эту проблему?

Я знаю, что могу просто использовать метод для каждого поля, отображающего отформатированное значение в виде строки, но я хотел знать, был ли способ DRYer.

ответ

2

Для отображения в списке администратора, вы можете сделать собственную функцию в вашем 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

Несомненно, но я должен сделать метод для каждого поля. Это не похоже на DRY-решение –

+0

или используйте «{: .2f}». Format (obj.amount) – radtek

0

Или создать класс, как это и наследовать от него

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 %%')) 
+0

У меня больше нет кода, но похоже, что это может сработать: S Я попробую, когда У меня есть время проверить его, чтобы я мог принять ответ –

0

До 0.12 версия django-money денежное представление частично поддерживалось администратором Django.

Начиная с версии 0.12 (выпущено 22.10.2017) все 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 
)