summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorMarc Garcia <garcia.marc@gmail.com>2009-07-08 00:52:25 +0000
committerMarc Garcia <garcia.marc@gmail.com>2009-07-08 00:52:25 +0000
commit07ed7fea103ee7f507fb2e49cdd6d983fe54c7b0 (patch)
treeb2a05285d0f10c466d5da7040c44ac424d72d67b /django
parent5b616f27c67f087b9f93f10804b175dee4c46839 (diff)
[soc2009/i18n] formatting system in development
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/i18n-improvements@11204 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r--django/conf/global_settings.py25
-rw-r--r--django/conf/locale/ca/formats.py4
-rw-r--r--django/contrib/admin/templatetags/admin_list.py14
-rw-r--r--django/template/defaultfilters.py5
-rw-r--r--django/utils/formats.py48
-rw-r--r--django/utils/numberformat.py32
6 files changed, 86 insertions, 42 deletions
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index a8f180a426..e09164e530 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -259,6 +259,12 @@ FILE_UPLOAD_TEMP_DIR = None
# you'd pass directly to os.chmod; see http://docs.python.org/lib/os-file-dir.html.
FILE_UPLOAD_PERMISSIONS = None
+# Python module path where user will place custom format definition.
+# The directory where this setting is pointing should contain subdirectories
+# named as the locales, containing a formats.py file
+# (i.e. "myproject.locale" for myproject/locale/en/formats.py etc. use)
+FORMAT_MODULE_PATH = None
+
# Default formatting for date objects. See all available format strings here:
# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
DATE_FORMAT = 'N j, Y'
@@ -283,21 +289,28 @@ MONTH_DAY_FORMAT = 'F j'
# Default shortformatting for date objects. See all available format strings here:
# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
-SHORT_DATE_FORMAT = 'N j, Y'
+SHORT_DATE_FORMAT = 'm/d/Y'
# Default short formatting for datetime objects.
# See all available format strings here:
# http://docs.djangoproject.com/en/dev/ref/templates/builtins/#now
-SHORT_DATETIME_FORMAT = 'N j, Y, P'
+SHORT_DATETIME_FORMAT = 'm/d/Y P'
-# Default first day of week, to be used on calendars
-# 0 means Sunday
+# First day of week, to be used on calendars
+# 0 means Sunday, 1 means Monday...
FIRST_DAY_OF_WEEK = 0
-# Default decimal separator symbol
+# Decimal separator symbol
DECIMAL_SEPARATOR = '.'
-# Default thousand separator symbol
+# Boolean that sets whether to add thousand separator when formatting numbers
+USE_THOUSAND_SEPARATOR = False
+
+# Number of digits that will be togheter, when spliting them by THOUSAND_SEPARATOR
+# 0 means no grouping, 3 means splitting by thousands...
+NUMBER_GROUPING = 0
+
+# Thousand separator symbol
THOUSAND_SEPARATOR = ','
# Do you want to manage transactions manually?
diff --git a/django/conf/locale/ca/formats.py b/django/conf/locale/ca/formats.py
index 414fe86e26..cc8a494f7c 100644
--- a/django/conf/locale/ca/formats.py
+++ b/django/conf/locale/ca/formats.py
@@ -3,7 +3,7 @@
DATE_FORMAT = 'j \de F \de Y'
DATETIME_FORMAT = 'j \de F \de Y \\a \le\s H:i'
-TIME_FORMAT = 'P'
+TIME_FORMAT = 'H:i'
YEAR_MONTH_FORMAT = 'F \de Y'
MONTH_DAY_FORMAT = 'j \de F'
@@ -14,5 +14,5 @@ FIRST_DAY_OF_WEEK = 1 # 0 means Sunday
DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = '.'
-
+NUMBER_GROUPING = 3
diff --git a/django/contrib/admin/templatetags/admin_list.py b/django/contrib/admin/templatetags/admin_list.py
index 45bab2d6b4..add72037bb 100644
--- a/django/contrib/admin/templatetags/admin_list.py
+++ b/django/contrib/admin/templatetags/admin_list.py
@@ -8,7 +8,6 @@ from django.utils.html import escape, conditional_escape
from django.utils.text import capfirst
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext as _
-from django.utils.formats import localize
from django.utils.encoding import smart_unicode, smart_str, force_unicode
from django.template import Library
import datetime
@@ -183,14 +182,17 @@ def items_for_result(cl, result, form):
else:
result_repr = EMPTY_CHANGELIST_VALUE
# Dates and times are special: They're formatted in a certain way.
- elif isinstance(f, models.DateField) or isinstance(f, models.TimeField) or isinstance(f, models.DecimalField):
+ elif isinstance(f, models.DateField) or isinstance(f, models.TimeField):
if field_val:
- result_repr = localize(field_val)
- # result_repr = ('%%.%sf' % f.decimal_places) % field_val
+ result_repr = formats.localize(field_val)
else:
result_repr = EMPTY_CHANGELIST_VALUE
- if not isinstance(f, models.DecimalField):
- row_class = ' class="nowrap"'
+ elif isinstance(f, models.DecimalField):
+ if field_val:
+ result_repr = formats.number_format(field_val, f.decimal_places)
+ else:
+ result_repr = EMPTY_CHANGELIST_VALUE
+ row_class = ' class="nowrap"'
# Booleans are special: We use images.
elif isinstance(f, models.BooleanField) or isinstance(f, models.NullBooleanField):
result_repr = _boolean_icon(field_val)
diff --git a/django/template/defaultfilters.py b/django/template/defaultfilters.py
index 47e116cd1a..94108f2d23 100644
--- a/django/template/defaultfilters.py
+++ b/django/template/defaultfilters.py
@@ -18,6 +18,7 @@ from django.conf import settings
from django.utils.translation import ugettext, ungettext
from django.utils.encoding import force_unicode, iri_to_uri
from django.utils.safestring import mark_safe, SafeData
+from django.utils.formats import number_format
register = Library()
@@ -166,14 +167,14 @@ def floatformat(text, arg=-1):
return input_val
if not m and p < 0:
- return mark_safe(u'%d' % (int(d)))
+ return mark_safe(number_format(u'%d' % (int(d)), 0))
if p == 0:
exp = Decimal(1)
else:
exp = Decimal('1.0') / (Decimal(10) ** abs(p))
try:
- return mark_safe(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)))
+ return mark_safe(number_format(u'%s' % str(d.quantize(exp, ROUND_HALF_UP)), abs(p)))
except InvalidOperation:
return input_val
floatformat.is_safe = True
diff --git a/django/utils/formats.py b/django/utils/formats.py
index ad22e7600c..2b8e2704c0 100644
--- a/django/utils/formats.py
+++ b/django/utils/formats.py
@@ -1,6 +1,8 @@
import decimal
import datetime
+from django.conf import settings
+from django.utils.translation import get_language
from django.utils.importlib import import_module
from django.utils import dateformat
from django.utils import numberformat
@@ -11,7 +13,6 @@ def getformat_null(format_type):
set on the settings.
format_type is the name of the format, for example 'DATE_FORMAT'
"""
- from django.conf import settings
return getattr(settings, format_type)
def getformat_real(format_type):
@@ -20,15 +21,21 @@ def getformat_real(format_type):
current language (locale) defaulting to the format on settings.
format_type is the name of the format, for example 'DATE_FORMAT'
"""
- from django.utils.translation import get_language
import_formats = lambda s: import_module('.formats', 'django.conf.locale.%s' % s)
- tmp = import_formats('ca')
- format = None
- try:
- module = import_formats(get_language())
- except ImportError:
- pass
- else:
+ module = format = None
+ if settings.FORMAT_MODULE_PATH:
+ try:
+ module = import_module('.formats', '%s.%s' % (settings.FORMAT_MODULE_PATH, get_language()))
+ except ImportError:
+ pass
+
+ if not module:
+ try:
+ module = import_module('.formats', 'django.conf.locale.%s' % get_language())
+ except ImportError:
+ pass
+
+ if module:
try:
format = getattr(module, format_type)
except AttributeError:
@@ -37,28 +44,43 @@ def getformat_real(format_type):
# getformat will just return the value on setings if
# we don't use i18n in our project
-from django.conf import settings
if settings.USE_I18N and settings.USE_FORMAT_I18N:
getformat = getformat_real
else:
getformat = getformat_null
def date_format(value, format=None):
+ """
+ Formats a datetime.date or datetime.datetime object using a
+ localizable format
+ """
return dateformat.format(value, getformat(format or 'DATE_FORMAT'))
-def number_format(value):
+def number_format(value, decimal_pos=None):
+ """
+ Formats a numeric value using localization settings
+ """
return numberformat.format(
value,
getformat('DECIMAL_SEPARATOR'),
- 2, # TODO: decide how to set decimal positions later
- 3, # TODO: get it from formats
+ decimal_pos,
+ getformat('NUMBER_GROUPING'),
getformat('THOUSAND_SEPARATOR'),
)
def localize(value):
+ """
+ Checks value, and if it has a localizable type (date,
+ number...) it returns the value as a string using
+ current locale format
+ """
if settings.USE_I18N and settings.USE_FORMAT_I18N:
if isinstance(value, decimal.Decimal):
return number_format(value)
+ elif isinstance(value, float):
+ return number_format(value)
+ elif isinstance(value, int):
+ return number_format(value)
elif isinstance(value, datetime.datetime):
return date_format(value, 'DATETIME_FORMAT')
elif isinstance(value, datetime.date):
diff --git a/django/utils/numberformat.py b/django/utils/numberformat.py
index 0abf5b35c5..6223dbc26f 100644
--- a/django/utils/numberformat.py
+++ b/django/utils/numberformat.py
@@ -1,5 +1,13 @@
-def format(number, decimal_sep, decimal_pos, groupping=0, thousand_sep=''):
+from django.conf import settings
+
+def format(number, decimal_sep, decimal_pos, grouping=0, thousand_sep=''):
"""
+ Gets a number (as a number or string), and returns it as a string,
+ using formats definied as arguments:
+ * decimal_sep: Decimal separator symbol (for example ".")
+ * decimal_pos: Number of decimal positions
+ * grouping: Number of digits in every group limited by thousand separator
+ * thousand_sep: Thousand separator symbol (for example ",")
"""
# sign
if number < 0:
@@ -7,28 +15,26 @@ def format(number, decimal_sep, decimal_pos, groupping=0, thousand_sep=''):
else:
sign = ''
# decimal part
- str_number = str(abs(number))
+ str_number = unicode(number)
+ if str_number[0] == '-':
+ str_number = str_number[1:]
if '.' in str_number:
int_part, dec_part = str_number.split('.')
- dec_part = dec_part[:decimal_pos]
+ if decimal_pos:
+ dec_part = dec_part[:decimal_pos]
else:
int_part, dec_part = str_number, ''
- dec_part = dec_part + ('0' * (decimal_pos - len(dec_part)))
+ if decimal_pos:
+ dec_part = dec_part + ('0' * (decimal_pos - len(dec_part)))
if dec_part: dec_part = decimal_sep + dec_part
- # groupping
- if groupping:
+ # grouping
+ if settings.USE_THOUSAND_SEPARATOR and grouping:
int_part_gd = ''
for cnt, digit in enumerate(int_part[::-1]):
- if cnt and not cnt % groupping:
+ if cnt and not cnt % grouping:
int_part_gd += thousand_sep
int_part_gd += digit
int_part = int_part_gd[::-1]
-
return sign + int_part + dec_part
-if __name__ == '__main__':
- import decimal
- print format_number(-1000000, ',', 4, 3, '.')
- print format_number(-100.100, ',', 4, 3, '.')
- print format_number(decimal.Decimal('1000.100'), ',', 4)