web/lib/django/utils/formats.py
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     1 import decimal
       
     2 import datetime
       
     3 
       
     4 from django.conf import settings
       
     5 from django.utils.translation import get_language, to_locale, check_for_language
       
     6 from django.utils.importlib import import_module
       
     7 from django.utils.encoding import smart_str
       
     8 from django.utils import dateformat, numberformat, datetime_safe
       
     9 
       
    10 def get_format_modules(reverse=False):
       
    11     """
       
    12     Returns an iterator over the format modules found in the project and Django
       
    13     """
       
    14     modules = []
       
    15     if not check_for_language(get_language()) or not settings.USE_L10N:
       
    16         return modules
       
    17     locale = to_locale(get_language())
       
    18     if settings.FORMAT_MODULE_PATH:
       
    19         format_locations = [settings.FORMAT_MODULE_PATH + '.%s']
       
    20     else:
       
    21         format_locations = []
       
    22     format_locations.append('django.conf.locale.%s')
       
    23     for location in format_locations:
       
    24         for l in (locale, locale.split('_')[0]):
       
    25             try:
       
    26                 mod = import_module('.formats', location % l)
       
    27             except ImportError:
       
    28                 pass
       
    29             else:
       
    30                 # Don't return duplicates
       
    31                 if mod not in modules:
       
    32                     modules.append(mod)
       
    33     if reverse:
       
    34         modules.reverse()
       
    35     return modules
       
    36 
       
    37 def get_format(format_type):
       
    38     """
       
    39     For a specific format type, returns the format for the current
       
    40     language (locale), defaults to the format in the settings.
       
    41     format_type is the name of the format, e.g. 'DATE_FORMAT'
       
    42     """
       
    43     format_type = smart_str(format_type)
       
    44     if settings.USE_L10N:
       
    45         for module in get_format_modules():
       
    46             try:
       
    47                 return getattr(module, format_type)
       
    48             except AttributeError:
       
    49                 pass
       
    50     return getattr(settings, format_type)
       
    51 
       
    52 def date_format(value, format=None):
       
    53     """
       
    54     Formats a datetime.date or datetime.datetime object using a
       
    55     localizable format
       
    56     """
       
    57     return dateformat.format(value, get_format(format or 'DATE_FORMAT'))
       
    58 
       
    59 def time_format(value, format=None):
       
    60     """
       
    61     Formats a datetime.time object using a localizable format
       
    62     """
       
    63     return dateformat.time_format(value, get_format(format or 'TIME_FORMAT'))
       
    64 
       
    65 def number_format(value, decimal_pos=None):
       
    66     """
       
    67     Formats a numeric value using localization settings
       
    68     """
       
    69     return numberformat.format(
       
    70         value,
       
    71         get_format('DECIMAL_SEPARATOR'),
       
    72         decimal_pos,
       
    73         get_format('NUMBER_GROUPING'),
       
    74         get_format('THOUSAND_SEPARATOR'),
       
    75     )
       
    76 
       
    77 def localize(value):
       
    78     """
       
    79     Checks if value is a localizable type (date, number...) and returns it
       
    80     formatted as a string using current locale format
       
    81     """
       
    82     if settings.USE_L10N:
       
    83         if isinstance(value, (decimal.Decimal, float, int)):
       
    84             return number_format(value)
       
    85         elif isinstance(value, datetime.datetime):
       
    86             return date_format(value, 'DATETIME_FORMAT')
       
    87         elif isinstance(value, datetime.date):
       
    88             return date_format(value)
       
    89         elif isinstance(value, datetime.time):
       
    90             return time_format(value, 'TIME_FORMAT')
       
    91     return value
       
    92 
       
    93 def localize_input(value, default=None):
       
    94     """
       
    95     Checks if an input value is a localizable type and returns it
       
    96     formatted with the appropriate formatting string of the current locale.
       
    97     """
       
    98     if isinstance(value, (decimal.Decimal, float, int)):
       
    99         return number_format(value)
       
   100     if isinstance(value, datetime.datetime):
       
   101         value = datetime_safe.new_datetime(value)
       
   102         format = smart_str(default or get_format('DATETIME_INPUT_FORMATS')[0])
       
   103         return value.strftime(format)
       
   104     elif isinstance(value, datetime.date):
       
   105         value = datetime_safe.new_date(value)
       
   106         format = smart_str(default or get_format('DATE_INPUT_FORMATS')[0])
       
   107         return value.strftime(format)
       
   108     elif isinstance(value, datetime.time):
       
   109         format = smart_str(default or get_format('TIME_INPUT_FORMATS')[0])
       
   110         return value.strftime(format)
       
   111     return value
       
   112 
       
   113 def sanitize_separators(value):
       
   114     """
       
   115     Sanitizes a value according to the current decimal and
       
   116     thousand separator setting. Used with form field input.
       
   117     """
       
   118     if settings.USE_L10N:
       
   119         decimal_separator = get_format('DECIMAL_SEPARATOR')
       
   120         if isinstance(value, basestring):
       
   121             parts = []
       
   122             if decimal_separator in value:
       
   123                 value, decimals = value.split(decimal_separator, 1)
       
   124                 parts.append(decimals)
       
   125             if settings.USE_THOUSAND_SEPARATOR:
       
   126                 parts.append(value.replace(get_format('THOUSAND_SEPARATOR'), ''))
       
   127             else:
       
   128                 parts.append(value)
       
   129             value = '.'.join(reversed(parts))
       
   130     return value