Fixed #32873 -- Deprecated settings.USE_L10N.
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
This commit is contained in:
parent
04e023e383
commit
676bd084f2
|
@ -9,9 +9,11 @@ for a list of all possible variables.
|
||||||
import importlib
|
import importlib
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
import traceback
|
||||||
import warnings
|
import warnings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
import django
|
||||||
from django.conf import global_settings
|
from django.conf import global_settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils.deprecation import RemovedInDjango50Warning
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
|
@ -19,6 +21,12 @@ from django.utils.functional import LazyObject, empty
|
||||||
|
|
||||||
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
|
||||||
|
|
||||||
|
USE_L10N_DEPRECATED_MSG = (
|
||||||
|
'The USE_L10N setting is deprecated. Starting with Django 5.0, localized '
|
||||||
|
'formatting of data will always be enabled. For example Django will '
|
||||||
|
'display numbers and dates using the format of the current locale.'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SettingsReference(str):
|
class SettingsReference(str):
|
||||||
"""
|
"""
|
||||||
|
@ -129,6 +137,27 @@ class LazySettings(LazyObject):
|
||||||
"""Return True if the settings have already been configured."""
|
"""Return True if the settings have already been configured."""
|
||||||
return self._wrapped is not empty
|
return self._wrapped is not empty
|
||||||
|
|
||||||
|
@property
|
||||||
|
def USE_L10N(self):
|
||||||
|
stack = traceback.extract_stack()
|
||||||
|
# Show a warning if the setting is used outside of Django.
|
||||||
|
# Stack index: -1 this line, -2 the caller.
|
||||||
|
filename, _, _, _ = stack[-2]
|
||||||
|
if not filename.startswith(os.path.dirname(django.__file__)):
|
||||||
|
warnings.warn(
|
||||||
|
USE_L10N_DEPRECATED_MSG,
|
||||||
|
RemovedInDjango50Warning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return self.__getattr__('USE_L10N')
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning.
|
||||||
|
@property
|
||||||
|
def _USE_L10N_INTERNAL(self):
|
||||||
|
# Special hook to avoid checking a traceback in internal use on hot
|
||||||
|
# paths.
|
||||||
|
return self.__getattr__('USE_L10N')
|
||||||
|
|
||||||
|
|
||||||
class Settings:
|
class Settings:
|
||||||
def __init__(self, settings_module):
|
def __init__(self, settings_module):
|
||||||
|
@ -179,6 +208,9 @@ class Settings:
|
||||||
os.environ['TZ'] = self.TIME_ZONE
|
os.environ['TZ'] = self.TIME_ZONE
|
||||||
time.tzset()
|
time.tzset()
|
||||||
|
|
||||||
|
if self.is_overridden('USE_L10N'):
|
||||||
|
warnings.warn(USE_L10N_DEPRECATED_MSG, RemovedInDjango50Warning)
|
||||||
|
|
||||||
def is_overridden(self, setting):
|
def is_overridden(self, setting):
|
||||||
return setting in self._explicit_settings
|
return setting in self._explicit_settings
|
||||||
|
|
||||||
|
@ -210,6 +242,8 @@ class UserSettingsHolder:
|
||||||
|
|
||||||
def __setattr__(self, name, value):
|
def __setattr__(self, name, value):
|
||||||
self._deleted.discard(name)
|
self._deleted.discard(name)
|
||||||
|
if name == 'USE_L10N':
|
||||||
|
warnings.warn(USE_L10N_DEPRECATED_MSG, RemovedInDjango50Warning)
|
||||||
super().__setattr__(name, value)
|
super().__setattr__(name, value)
|
||||||
|
|
||||||
def __delattr__(self, name):
|
def __delattr__(self, name):
|
||||||
|
|
|
@ -167,7 +167,7 @@ LANGUAGE_COOKIE_SAMESITE = None
|
||||||
|
|
||||||
# If you set this to True, Django will format dates, numbers and calendars
|
# If you set this to True, Django will format dates, numbers and calendars
|
||||||
# according to user current locale.
|
# according to user current locale.
|
||||||
USE_L10N = False
|
USE_L10N = True
|
||||||
|
|
||||||
# Not-necessarily-technical managers of the site. They get broken link
|
# Not-necessarily-technical managers of the site. They get broken link
|
||||||
# notifications and other various emails.
|
# notifications and other various emails.
|
||||||
|
|
|
@ -2,24 +2,36 @@
|
||||||
#
|
#
|
||||||
# The *_FORMAT strings use the Django date format syntax,
|
# The *_FORMAT strings use the Django date format syntax,
|
||||||
# see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
|
# see https://docs.djangoproject.com/en/dev/ref/templates/builtins/#date
|
||||||
DATE_FORMAT = 'N j, Y'
|
|
||||||
TIME_FORMAT = 'P'
|
|
||||||
DATETIME_FORMAT = 'N j, Y, P'
|
|
||||||
YEAR_MONTH_FORMAT = 'F Y'
|
|
||||||
MONTH_DAY_FORMAT = 'F j'
|
|
||||||
SHORT_DATE_FORMAT = 'm/d/Y'
|
|
||||||
SHORT_DATETIME_FORMAT = 'm/d/Y P'
|
|
||||||
FIRST_DAY_OF_WEEK = 0 # Sunday
|
|
||||||
|
|
||||||
|
# Formatting for date objects.
|
||||||
|
DATE_FORMAT = 'N j, Y'
|
||||||
|
# Formatting for time objects.
|
||||||
|
TIME_FORMAT = 'P'
|
||||||
|
# Formatting for datetime objects.
|
||||||
|
DATETIME_FORMAT = 'N j, Y, P'
|
||||||
|
# Formatting for date objects when only the year and month are relevant.
|
||||||
|
YEAR_MONTH_FORMAT = 'F Y'
|
||||||
|
# Formatting for date objects when only the month and day are relevant.
|
||||||
|
MONTH_DAY_FORMAT = 'F j'
|
||||||
|
# Short formatting for date objects.
|
||||||
|
SHORT_DATE_FORMAT = 'm/d/Y'
|
||||||
|
# Short formatting for datetime objects.
|
||||||
|
SHORT_DATETIME_FORMAT = 'm/d/Y P'
|
||||||
|
# First day of week, to be used on calendars.
|
||||||
|
# 0 means Sunday, 1 means Monday...
|
||||||
|
FIRST_DAY_OF_WEEK = 0
|
||||||
|
|
||||||
|
# Formats to be used when parsing dates from input boxes, in order.
|
||||||
# The *_INPUT_FORMATS strings use the Python strftime format syntax,
|
# The *_INPUT_FORMATS strings use the Python strftime format syntax,
|
||||||
# see https://docs.python.org/library/datetime.html#strftime-strptime-behavior
|
# see https://docs.python.org/library/datetime.html#strftime-strptime-behavior
|
||||||
|
# Note that these format strings are different from the ones to display dates.
|
||||||
# Kept ISO formats as they are in first position
|
# Kept ISO formats as they are in first position
|
||||||
DATE_INPUT_FORMATS = [
|
DATE_INPUT_FORMATS = [
|
||||||
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
|
'%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
|
||||||
# '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
|
'%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
|
||||||
# '%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
|
'%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
|
||||||
# '%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
|
'%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
|
||||||
# '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
|
'%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
|
||||||
]
|
]
|
||||||
DATETIME_INPUT_FORMATS = [
|
DATETIME_INPUT_FORMATS = [
|
||||||
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
|
'%Y-%m-%d %H:%M:%S', # '2006-10-25 14:30:59'
|
||||||
|
@ -32,6 +44,16 @@ DATETIME_INPUT_FORMATS = [
|
||||||
'%m/%d/%y %H:%M:%S.%f', # '10/25/06 14:30:59.000200'
|
'%m/%d/%y %H:%M:%S.%f', # '10/25/06 14:30:59.000200'
|
||||||
'%m/%d/%y %H:%M', # '10/25/06 14:30'
|
'%m/%d/%y %H:%M', # '10/25/06 14:30'
|
||||||
]
|
]
|
||||||
|
TIME_INPUT_FORMATS = [
|
||||||
|
'%H:%M:%S', # '14:30:59'
|
||||||
|
'%H:%M:%S.%f', # '14:30:59.000200'
|
||||||
|
'%H:%M', # '14:30'
|
||||||
|
]
|
||||||
|
|
||||||
|
# Decimal separator symbol.
|
||||||
DECIMAL_SEPARATOR = '.'
|
DECIMAL_SEPARATOR = '.'
|
||||||
|
# Thousand separator symbol.
|
||||||
THOUSAND_SEPARATOR = ','
|
THOUSAND_SEPARATOR = ','
|
||||||
|
# Number of digits that will be together, when splitting them by
|
||||||
|
# THOUSAND_SEPARATOR. 0 means no grouping, 3 means splitting by thousands.
|
||||||
NUMBER_GROUPING = 3
|
NUMBER_GROUPING = 3
|
||||||
|
|
|
@ -109,8 +109,6 @@ TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
USE_L10N = True
|
|
||||||
|
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,11 @@ def get_format(format_type, lang=None, use_l10n=None):
|
||||||
If use_l10n is provided and is not None, it forces the value to
|
If use_l10n is provided and is not None, it forces the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
"""
|
"""
|
||||||
use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N)
|
use_l10n = use_l10n or (use_l10n is None and (
|
||||||
|
settings._USE_L10N_INTERNAL
|
||||||
|
if hasattr(settings, '_USE_L10N_INTERNAL')
|
||||||
|
else settings.USE_L10N
|
||||||
|
))
|
||||||
if use_l10n and lang is None:
|
if use_l10n and lang is None:
|
||||||
lang = get_language()
|
lang = get_language()
|
||||||
cache_key = (format_type, lang)
|
cache_key = (format_type, lang)
|
||||||
|
@ -168,7 +172,11 @@ def number_format(value, decimal_pos=None, use_l10n=None, force_grouping=False):
|
||||||
If use_l10n is provided and is not None, it forces the value to
|
If use_l10n is provided and is not None, it forces the value to
|
||||||
be localized (or not), overriding the value of settings.USE_L10N.
|
be localized (or not), overriding the value of settings.USE_L10N.
|
||||||
"""
|
"""
|
||||||
use_l10n = use_l10n or (use_l10n is None and settings.USE_L10N)
|
use_l10n = use_l10n or (use_l10n is None and (
|
||||||
|
settings._USE_L10N_INTERNAL
|
||||||
|
if hasattr(settings, '_USE_L10N_INTERNAL')
|
||||||
|
else settings.USE_L10N
|
||||||
|
))
|
||||||
lang = get_language() if use_l10n else None
|
lang = get_language() if use_l10n else None
|
||||||
return numberformat.format(
|
return numberformat.format(
|
||||||
value,
|
value,
|
||||||
|
|
|
@ -34,6 +34,8 @@ details on these changes.
|
||||||
``StringAgg`` aggregates will return ``None`` when there are no rows instead
|
``StringAgg`` aggregates will return ``None`` when there are no rows instead
|
||||||
of ``[]``, ``[]``, and ``''`` respectively.
|
of ``[]``, ``[]``, and ``''`` respectively.
|
||||||
|
|
||||||
|
* The ``USE_L10N`` setting will be removed.
|
||||||
|
|
||||||
.. _deprecation-removed-in-4.1:
|
.. _deprecation-removed-in-4.1:
|
||||||
|
|
||||||
4.1
|
4.1
|
||||||
|
|
|
@ -2774,7 +2774,7 @@ See also :setting:`LANGUAGE_CODE`, :setting:`USE_L10N` and :setting:`USE_TZ`.
|
||||||
``USE_L10N``
|
``USE_L10N``
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Default: ``False``
|
Default: ``True``
|
||||||
|
|
||||||
A boolean that specifies if localized formatting of data will be enabled by
|
A boolean that specifies if localized formatting of data will be enabled by
|
||||||
default or not. If this is set to ``True``, e.g. Django will display numbers and
|
default or not. If this is set to ``True``, e.g. Django will display numbers and
|
||||||
|
@ -2782,10 +2782,15 @@ dates using the format of the current locale.
|
||||||
|
|
||||||
See also :setting:`LANGUAGE_CODE`, :setting:`USE_I18N` and :setting:`USE_TZ`.
|
See also :setting:`LANGUAGE_CODE`, :setting:`USE_I18N` and :setting:`USE_TZ`.
|
||||||
|
|
||||||
.. note::
|
.. versionchanged:: 4.0
|
||||||
|
|
||||||
The default :file:`settings.py` file created by :djadmin:`django-admin
|
In older versions, the default value is ``False``.
|
||||||
startproject <startproject>` includes ``USE_L10N = True`` for convenience.
|
|
||||||
|
.. deprecated:: 4.0
|
||||||
|
|
||||||
|
This setting is deprecated. Starting with Django 5.0, localized formatting
|
||||||
|
of data will always be enabled. For example Django will display numbers and
|
||||||
|
dates using the format of the current locale.
|
||||||
|
|
||||||
.. setting:: USE_THOUSAND_SEPARATOR
|
.. setting:: USE_THOUSAND_SEPARATOR
|
||||||
|
|
||||||
|
|
|
@ -918,7 +918,7 @@ Miscellaneous
|
||||||
To adapt, move the fragment outside the template tag:
|
To adapt, move the fragment outside the template tag:
|
||||||
``{% static 'img.svg' %}#fragment``.
|
``{% static 'img.svg' %}#fragment``.
|
||||||
|
|
||||||
* When :setting:`USE_L10N` is ``True``, localization is now applied for the
|
* When ``USE_L10N`` is ``True``, localization is now applied for the
|
||||||
:tfilter:`date` and :tfilter:`time` filters when no format string is
|
:tfilter:`date` and :tfilter:`time` filters when no format string is
|
||||||
specified. The ``DATE_FORMAT`` and ``TIME_FORMAT`` specifiers from the active
|
specified. The ``DATE_FORMAT`` and ``TIME_FORMAT`` specifiers from the active
|
||||||
locale are used instead of the settings of the same name.
|
locale are used instead of the settings of the same name.
|
||||||
|
|
|
@ -936,7 +936,7 @@ Date format helper functions
|
||||||
``django.utils.translation.get_date_formats()`` and
|
``django.utils.translation.get_date_formats()`` and
|
||||||
``django.utils.translation.get_partial_date_formats()`` have been deprecated
|
``django.utils.translation.get_partial_date_formats()`` have been deprecated
|
||||||
in favor of the appropriate calls to ``django.utils.formats.get_format()``,
|
in favor of the appropriate calls to ``django.utils.formats.get_format()``,
|
||||||
which is locale-aware when :setting:`USE_L10N` is set to ``True``, and falls
|
which is locale-aware when ``USE_L10N`` is set to ``True``, and falls
|
||||||
back to default settings if set to ``False``.
|
back to default settings if set to ``False``.
|
||||||
|
|
||||||
To get the different date formats, instead of writing this::
|
To get the different date formats, instead of writing this::
|
||||||
|
|
|
@ -558,7 +558,7 @@ Miscellaneous
|
||||||
* :class:`~django.views.generic.base.RedirectView` no longer silences
|
* :class:`~django.views.generic.base.RedirectView` no longer silences
|
||||||
``NoReverseMatch`` if the ``pattern_name`` doesn't exist.
|
``NoReverseMatch`` if the ``pattern_name`` doesn't exist.
|
||||||
|
|
||||||
* When :setting:`USE_L10N` is off, :class:`~django.forms.FloatField` and
|
* When ``USE_L10N`` is off, :class:`~django.forms.FloatField` and
|
||||||
:class:`~django.forms.DecimalField` now respect :setting:`DECIMAL_SEPARATOR`
|
:class:`~django.forms.DecimalField` now respect :setting:`DECIMAL_SEPARATOR`
|
||||||
and :setting:`THOUSAND_SEPARATOR` during validation. For example, with the
|
and :setting:`THOUSAND_SEPARATOR` during validation. For example, with the
|
||||||
settings::
|
settings::
|
||||||
|
|
|
@ -672,7 +672,7 @@ Miscellaneous
|
||||||
and underscores.
|
and underscores.
|
||||||
|
|
||||||
* The :tfilter:`intcomma` and :tfilter:`intword` template filters no longer
|
* The :tfilter:`intcomma` and :tfilter:`intword` template filters no longer
|
||||||
depend on the :setting:`USE_L10N` setting.
|
depend on the ``USE_L10N`` setting.
|
||||||
|
|
||||||
* Support for ``argon2-cffi`` < 19.1.0 is removed.
|
* Support for ``argon2-cffi`` < 19.1.0 is removed.
|
||||||
|
|
||||||
|
|
|
@ -579,8 +579,11 @@ Miscellaneous
|
||||||
Django 3.2.
|
Django 3.2.
|
||||||
|
|
||||||
* The :tfilter:`floatformat` template filter no longer depends on the
|
* The :tfilter:`floatformat` template filter no longer depends on the
|
||||||
:setting:`USE_L10N` setting and always returns localized output. Use the
|
``USE_L10N`` setting and always returns localized output. Use the ``u``
|
||||||
``u`` suffix to disable localization.
|
suffix to disable localization.
|
||||||
|
|
||||||
|
* The default value of the ``USE_L10N`` setting is changed to ``True``. See the
|
||||||
|
:ref:`Localization section <use_l10n_deprecation>` above for more details.
|
||||||
|
|
||||||
.. _deprecated-features-4.0:
|
.. _deprecated-features-4.0:
|
||||||
|
|
||||||
|
@ -601,6 +604,20 @@ Note that the default :file:`settings.py` file created by
|
||||||
You can set ``USE_TZ`` to ``False`` in your project settings before then to
|
You can set ``USE_TZ`` to ``False`` in your project settings before then to
|
||||||
opt-out.
|
opt-out.
|
||||||
|
|
||||||
|
.. _use_l10n_deprecation:
|
||||||
|
|
||||||
|
Localization
|
||||||
|
------------
|
||||||
|
|
||||||
|
In order to follow good practice, the default value of the ``USE_L10N`` setting
|
||||||
|
is changed from ``False`` to ``True``.
|
||||||
|
|
||||||
|
Moreover ``USE_L10N`` is deprecated as of this release. Starting with Django
|
||||||
|
5.0, by default, any date or number displayed by Django will be localized.
|
||||||
|
|
||||||
|
The :ttag:`{% localize %} <localize>` tag and the :tfilter:`localize`/
|
||||||
|
:tfilter:`unlocalize` filters will still be honored by Django.
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -18,18 +18,16 @@ necessary to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
The default :file:`settings.py` file created by :djadmin:`django-admin
|
To enable number formatting with thousand separators, it is necessary to
|
||||||
startproject <startproject>` includes :setting:`USE_L10N = True <USE_L10N>`
|
set :setting:`USE_THOUSAND_SEPARATOR = True <USE_THOUSAND_SEPARATOR>` in
|
||||||
for convenience. Note, however, that to enable number formatting with
|
your settings file. Alternatively, you could use :tfilter:`intcomma` to
|
||||||
thousand separators it is necessary to set :setting:`USE_THOUSAND_SEPARATOR
|
format numbers in your template.
|
||||||
= True <USE_THOUSAND_SEPARATOR>` in your settings file. Alternatively, you
|
|
||||||
could use :tfilter:`intcomma` to format numbers in your template.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
There is also an independent but related :setting:`USE_I18N` setting that
|
There is a related :setting:`USE_I18N` setting that controls if Django
|
||||||
controls if Django should activate translation. See
|
should activate translation. See :doc:`/topics/i18n/translation` for more
|
||||||
:doc:`/topics/i18n/translation` for more details.
|
details.
|
||||||
|
|
||||||
Locale aware input in forms
|
Locale aware input in forms
|
||||||
===========================
|
===========================
|
||||||
|
|
|
@ -47,12 +47,6 @@ functions in :mod:`django.utils.timezone`.
|
||||||
startproject <startproject>` includes :setting:`USE_TZ = True <USE_TZ>`
|
startproject <startproject>` includes :setting:`USE_TZ = True <USE_TZ>`
|
||||||
for convenience.
|
for convenience.
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
There is also an independent but related :setting:`USE_L10N` setting that
|
|
||||||
controls whether Django should activate format localization. See
|
|
||||||
:doc:`/topics/i18n/formatting` for more details.
|
|
||||||
|
|
||||||
If you're wrestling with a particular problem, start with the :ref:`time zone
|
If you're wrestling with a particular problem, start with the :ref:`time zone
|
||||||
FAQ <time-zones-faq>`.
|
FAQ <time-zones-faq>`.
|
||||||
|
|
||||||
|
|
|
@ -29,12 +29,6 @@ use internationalization, you should take the two seconds to set
|
||||||
:setting:`USE_I18N = False <USE_I18N>` in your settings file. Then Django will
|
:setting:`USE_I18N = False <USE_I18N>` in your settings file. Then Django will
|
||||||
make some optimizations so as not to load the internationalization machinery.
|
make some optimizations so as not to load the internationalization machinery.
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
There is also an independent but related :setting:`USE_L10N` setting that
|
|
||||||
controls if Django should implement format localization. See
|
|
||||||
:doc:`/topics/i18n/formatting` for more details.
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Make sure you've activated translation for your project (the fastest way is
|
Make sure you've activated translation for your project (the fastest way is
|
||||||
|
|
|
@ -382,7 +382,7 @@ class TestInline(TestDataMixin, TestCase):
|
||||||
html=True
|
html=True
|
||||||
)
|
)
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_localize_pk_shortcut(self):
|
def test_localize_pk_shortcut(self):
|
||||||
"""
|
"""
|
||||||
The "View on Site" link is correct for locales that use thousand
|
The "View on Site" link is correct for locales that use thousand
|
||||||
|
|
|
@ -74,7 +74,6 @@ class LogEntryTests(TestCase):
|
||||||
logentry = LogEntry(change_message='non-JSON string')
|
logentry = LogEntry(change_message='non-JSON string')
|
||||||
self.assertEqual(logentry.get_change_message(), logentry.change_message)
|
self.assertEqual(logentry.get_change_message(), logentry.change_message)
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
def test_logentry_change_message_localized_datetime_input(self):
|
def test_logentry_change_message_localized_datetime_input(self):
|
||||||
"""
|
"""
|
||||||
Localized date/time inputs shouldn't affect changed form data detection.
|
Localized date/time inputs shouldn't affect changed form data detection.
|
||||||
|
|
|
@ -201,7 +201,7 @@ class UtilsTests(SimpleTestCase):
|
||||||
display_value = display_for_field(12345, models.IntegerField(), self.empty_value)
|
display_value = display_for_field(12345, models.IntegerField(), self.empty_value)
|
||||||
self.assertEqual(display_value, '12345')
|
self.assertEqual(display_value, '12345')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_number_formats_with_thousand_separator_display_for_field(self):
|
def test_number_formats_with_thousand_separator_display_for_field(self):
|
||||||
display_value = display_for_field(12345.6789, models.FloatField(), self.empty_value)
|
display_value = display_for_field(12345.6789, models.FloatField(), self.empty_value)
|
||||||
self.assertEqual(display_value, '12,345.6789')
|
self.assertEqual(display_value, '12,345.6789')
|
||||||
|
@ -219,7 +219,7 @@ class UtilsTests(SimpleTestCase):
|
||||||
display_value = display_for_value([1, 2, 'buckle', 'my', 'shoe'], self.empty_value)
|
display_value = display_for_value([1, 2, 'buckle', 'my', 'shoe'], self.empty_value)
|
||||||
self.assertEqual(display_value, '1, 2, buckle, my, shoe')
|
self.assertEqual(display_value, '1, 2, buckle, my, shoe')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_list_display_for_value_boolean(self):
|
def test_list_display_for_value_boolean(self):
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
display_for_value(True, '', boolean=True),
|
display_for_value(True, '', boolean=True),
|
||||||
|
|
|
@ -72,7 +72,7 @@ class AdminActionsTest(TestCase):
|
||||||
self.assertContains(response, 'Are you sure you want to delete the selected subscribers?')
|
self.assertContains(response, 'Are you sure you want to delete the selected subscribers?')
|
||||||
self.assertContains(response, '<ul></ul>', html=True)
|
self.assertContains(response, '<ul></ul>', html=True)
|
||||||
|
|
||||||
@override_settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True, NUMBER_GROUPING=3)
|
@override_settings(USE_THOUSAND_SEPARATOR=True, NUMBER_GROUPING=3)
|
||||||
def test_non_localized_pk(self):
|
def test_non_localized_pk(self):
|
||||||
"""
|
"""
|
||||||
If USE_THOUSAND_SEPARATOR is set, the ids for the objects selected for
|
If USE_THOUSAND_SEPARATOR is set, the ids for the objects selected for
|
||||||
|
|
|
@ -109,7 +109,7 @@ class AdminFieldExtractionMixin:
|
||||||
return field
|
return field
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_views.urls', USE_I18N=True, USE_L10N=False, LANGUAGE_CODE='en')
|
@override_settings(ROOT_URLCONF='admin_views.urls', USE_I18N=True, LANGUAGE_CODE='en')
|
||||||
class AdminViewBasicTestCase(TestCase):
|
class AdminViewBasicTestCase(TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -802,12 +802,12 @@ class AdminViewBasicTest(AdminViewBasicTestCase):
|
||||||
response = self.client.get(reverse('admin-extra-context:jsi18n'))
|
response = self.client.get(reverse('admin-extra-context:jsi18n'))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
|
|
||||||
def test_L10N_deactivated(self):
|
def test_jsi18n_format_fallback(self):
|
||||||
"""
|
"""
|
||||||
Check if L10N is deactivated, the JavaScript i18n view doesn't
|
The JavaScript i18n view doesn't return localized date/time formats
|
||||||
return localized date/time formats. Refs #14824.
|
when the selected language cannot be found.
|
||||||
"""
|
"""
|
||||||
with self.settings(LANGUAGE_CODE='ru', USE_L10N=False), translation.override('none'):
|
with self.settings(LANGUAGE_CODE='ru'), translation.override('none'):
|
||||||
response = self.client.get(reverse('admin:jsi18n'))
|
response = self.client.get(reverse('admin:jsi18n'))
|
||||||
self.assertNotContains(response, '%d.%m.%Y %H:%M:%S')
|
self.assertNotContains(response, '%d.%m.%Y %H:%M:%S')
|
||||||
self.assertContains(response, '%Y-%m-%d %H:%M:%S')
|
self.assertContains(response, '%Y-%m-%d %H:%M:%S')
|
||||||
|
@ -4541,7 +4541,7 @@ class PrePopulatedTest(TestCase):
|
||||||
""id": "#id_prepopulatedsubpost_set-0-subslug""
|
""id": "#id_prepopulatedsubpost_set-0-subslug""
|
||||||
)
|
)
|
||||||
|
|
||||||
@override_settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_prepopulated_maxlength_localized(self):
|
def test_prepopulated_maxlength_localized(self):
|
||||||
"""
|
"""
|
||||||
Regression test for #15938: if USE_THOUSAND_SEPARATOR is set, make sure
|
Regression test for #15938: if USE_THOUSAND_SEPARATOR is set, make sure
|
||||||
|
@ -5704,7 +5704,7 @@ class ValidXHTMLTests(TestCase):
|
||||||
self.assertNotContains(response, ' xml:lang=""')
|
self.assertNotContains(response, ' xml:lang=""')
|
||||||
|
|
||||||
|
|
||||||
@override_settings(ROOT_URLCONF='admin_views.urls', USE_THOUSAND_SEPARATOR=True, USE_L10N=True)
|
@override_settings(ROOT_URLCONF='admin_views.urls', USE_THOUSAND_SEPARATOR=True)
|
||||||
class DateHierarchyTests(TestCase):
|
class DateHierarchyTests(TestCase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -338,7 +338,7 @@ class AdminSplitDateTimeWidgetTest(SimpleTestCase):
|
||||||
def test_localization(self):
|
def test_localization(self):
|
||||||
w = widgets.AdminSplitDateTime()
|
w = widgets.AdminSplitDateTime()
|
||||||
|
|
||||||
with self.settings(USE_L10N=True), translation.override('de-at'):
|
with translation.override('de-at'):
|
||||||
w.is_localized = True
|
w.is_localized = True
|
||||||
self.assertHTMLEqual(
|
self.assertHTMLEqual(
|
||||||
w.render('test', datetime(2007, 12, 1, 9, 30)),
|
w.render('test', datetime(2007, 12, 1, 9, 30)),
|
||||||
|
@ -939,7 +939,7 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
|
||||||
expected_caption = '{:s} {:d}'.format(may_translation.upper(), 1984)
|
expected_caption = '{:s} {:d}'.format(may_translation.upper(), 1984)
|
||||||
|
|
||||||
# Test with every locale
|
# Test with every locale
|
||||||
with override_settings(LANGUAGE_CODE=language_code, USE_L10N=True):
|
with override_settings(LANGUAGE_CODE=language_code):
|
||||||
|
|
||||||
# Open a page that has a date picker widget
|
# Open a page that has a date picker widget
|
||||||
url = reverse('admin:admin_widgets_member_change', args=(member.pk,))
|
url = reverse('admin:admin_widgets_member_change', args=(member.pk,))
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
import sys
|
||||||
|
from types import ModuleType
|
||||||
|
|
||||||
|
from django.conf import USE_L10N_DEPRECATED_MSG, Settings, settings
|
||||||
|
from django.test import TestCase, ignore_warnings
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
|
|
||||||
|
|
||||||
|
class DeprecationTests(TestCase):
|
||||||
|
msg = USE_L10N_DEPRECATED_MSG
|
||||||
|
|
||||||
|
def test_override_settings_warning(self):
|
||||||
|
# Warning is raised when USE_L10N is set in UserSettingsHolder (used by
|
||||||
|
# the @override_settings decorator).
|
||||||
|
with self.assertRaisesMessage(RemovedInDjango50Warning, self.msg):
|
||||||
|
with self.settings(USE_L10N=True):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_settings_init_warning(self):
|
||||||
|
settings_module = ModuleType('fake_settings_module')
|
||||||
|
settings_module.SECRET_KEY = 'foo'
|
||||||
|
settings_module.USE_TZ = True
|
||||||
|
settings_module.USE_L10N = False
|
||||||
|
sys.modules['fake_settings_module'] = settings_module
|
||||||
|
try:
|
||||||
|
with self.assertRaisesMessage(RemovedInDjango50Warning, self.msg):
|
||||||
|
Settings('fake_settings_module')
|
||||||
|
finally:
|
||||||
|
del sys.modules['fake_settings_module']
|
||||||
|
|
||||||
|
def test_access_warning(self):
|
||||||
|
with self.assertRaisesMessage(RemovedInDjango50Warning, self.msg):
|
||||||
|
settings.USE_L10N
|
||||||
|
# Works a second time.
|
||||||
|
with self.assertRaisesMessage(RemovedInDjango50Warning, self.msg):
|
||||||
|
settings.USE_L10N
|
||||||
|
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
|
def test_access(self):
|
||||||
|
with self.settings(USE_L10N=False):
|
||||||
|
self.assertIs(settings.USE_L10N, False)
|
||||||
|
# Works a second time.
|
||||||
|
self.assertIs(settings.USE_L10N, False)
|
|
@ -2,7 +2,7 @@ from datetime import date, datetime
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.forms import DateField, Form, HiddenInput, SelectDateWidget
|
from django.forms import DateField, Form, HiddenInput, SelectDateWidget
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,6 @@ class DateFieldTest(SimpleTestCase):
|
||||||
d = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
|
d = GetDate({'mydate_month': '1', 'mydate_day': '1', 'mydate_year': '2010'})
|
||||||
self.assertIn('<label for="id_mydate_month">', d.as_p())
|
self.assertIn('<label for="id_mydate_month">', d.as_p())
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('nl')
|
@translation.override('nl')
|
||||||
def test_l10n_date_changed(self):
|
def test_l10n_date_changed(self):
|
||||||
"""
|
"""
|
||||||
|
@ -95,7 +94,6 @@ class DateFieldTest(SimpleTestCase):
|
||||||
}, initial={'mydate': date(2008, 4, 1)})
|
}, initial={'mydate': date(2008, 4, 1)})
|
||||||
self.assertFalse(b.has_changed())
|
self.assertFalse(b.has_changed())
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('nl')
|
@translation.override('nl')
|
||||||
def test_l10n_invalid_date_in(self):
|
def test_l10n_invalid_date_in(self):
|
||||||
# Invalid dates shouldn't be allowed
|
# Invalid dates shouldn't be allowed
|
||||||
|
@ -104,7 +102,6 @@ class DateFieldTest(SimpleTestCase):
|
||||||
# 'Geef een geldige datum op.' = 'Enter a valid date.'
|
# 'Geef een geldige datum op.' = 'Enter a valid date.'
|
||||||
self.assertEqual(a.errors, {'mydate': ['Voer een geldige datum in.']})
|
self.assertEqual(a.errors, {'mydate': ['Voer een geldige datum in.']})
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('nl')
|
@translation.override('nl')
|
||||||
def test_form_label_association(self):
|
def test_form_label_association(self):
|
||||||
# label tag is correctly associated with first rendered dropdown
|
# label tag is correctly associated with first rendered dropdown
|
||||||
|
|
|
@ -2,8 +2,9 @@ import decimal
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.forms import DecimalField, NumberInput, Widget
|
from django.forms import DecimalField, NumberInput, Widget
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, ignore_warnings, override_settings
|
||||||
from django.utils import formats, translation
|
from django.utils import formats, translation
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
|
|
||||||
from . import FormFieldAssertionsMixin
|
from . import FormFieldAssertionsMixin
|
||||||
|
|
||||||
|
@ -153,17 +154,27 @@ class DecimalFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
|
||||||
self.assertFalse(f.has_changed(d, '0.10'))
|
self.assertFalse(f.has_changed(d, '0.10'))
|
||||||
self.assertTrue(f.has_changed(d, '0.101'))
|
self.assertTrue(f.has_changed(d, '0.101'))
|
||||||
|
|
||||||
with translation.override('fr'), self.settings(USE_L10N=True):
|
with translation.override('fr'):
|
||||||
f = DecimalField(max_digits=2, decimal_places=2, localize=True)
|
f = DecimalField(max_digits=2, decimal_places=2, localize=True)
|
||||||
localized_d = formats.localize_input(d) # -> '0,1' in French
|
localized_d = formats.localize_input(d) # -> '0,1' in French
|
||||||
self.assertFalse(f.has_changed(d, localized_d))
|
self.assertFalse(f.has_changed(d, localized_d))
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
|
# @ignore_warnings and USE_L10N=False. The test should remain because
|
||||||
|
# format-related settings will take precedence over locale-dictated
|
||||||
|
# formats.
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',')
|
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',')
|
||||||
def test_decimalfield_support_decimal_separator(self):
|
def test_decimalfield_support_decimal_separator(self):
|
||||||
f = DecimalField(localize=True)
|
f = DecimalField(localize=True)
|
||||||
self.assertEqual(f.clean('1001,10'), decimal.Decimal("1001.10"))
|
self.assertEqual(f.clean('1001,10'), decimal.Decimal("1001.10"))
|
||||||
self.assertEqual(f.clean('1001.10'), decimal.Decimal("1001.10"))
|
self.assertEqual(f.clean('1001.10'), decimal.Decimal("1001.10"))
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
|
# @ignore_warnings and USE_L10N=False. The test should remain because
|
||||||
|
# format-related settings will take precedence over locale-dictated
|
||||||
|
# formats.
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
|
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
|
||||||
THOUSAND_SEPARATOR='.')
|
THOUSAND_SEPARATOR='.')
|
||||||
def test_decimalfield_support_thousands_separator(self):
|
def test_decimalfield_support_thousands_separator(self):
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.forms import FloatField, NumberInput
|
from django.forms import FloatField, NumberInput
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.test.utils import override_settings
|
from django.test.utils import ignore_warnings, override_settings
|
||||||
from django.utils import formats, translation
|
from django.utils import formats, translation
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
|
|
||||||
from . import FormFieldAssertionsMixin
|
from . import FormFieldAssertionsMixin
|
||||||
|
|
||||||
|
@ -81,17 +82,27 @@ class FloatFieldTest(FormFieldAssertionsMixin, SimpleTestCase):
|
||||||
n = 4.35
|
n = 4.35
|
||||||
self.assertFalse(f.has_changed(n, '4.3500'))
|
self.assertFalse(f.has_changed(n, '4.3500'))
|
||||||
|
|
||||||
with translation.override('fr'), self.settings(USE_L10N=True):
|
with translation.override('fr'):
|
||||||
f = FloatField(localize=True)
|
f = FloatField(localize=True)
|
||||||
localized_n = formats.localize_input(n) # -> '4,35' in French
|
localized_n = formats.localize_input(n) # -> '4,35' in French
|
||||||
self.assertFalse(f.has_changed(n, localized_n))
|
self.assertFalse(f.has_changed(n, localized_n))
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
|
# @ignore_warnings and USE_L10N=False. The test should remain because
|
||||||
|
# format-related settings will take precedence over locale-dictated
|
||||||
|
# formats.
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',')
|
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',')
|
||||||
def test_decimalfield_support_decimal_separator(self):
|
def test_decimalfield_support_decimal_separator(self):
|
||||||
f = FloatField(localize=True)
|
f = FloatField(localize=True)
|
||||||
self.assertEqual(f.clean('1001,10'), 1001.10)
|
self.assertEqual(f.clean('1001,10'), 1001.10)
|
||||||
self.assertEqual(f.clean('1001.10'), 1001.10)
|
self.assertEqual(f.clean('1001.10'), 1001.10)
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
|
# @ignore_warnings and USE_L10N=False. The test should remain because
|
||||||
|
# format-related settings will take precedence over locale-dictated
|
||||||
|
# formats.
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
|
@override_settings(USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
|
||||||
THOUSAND_SEPARATOR='.')
|
THOUSAND_SEPARATOR='.')
|
||||||
def test_decimalfield_support_thousands_separator(self):
|
def test_decimalfield_support_thousands_separator(self):
|
||||||
|
|
|
@ -3,10 +3,10 @@ from datetime import date, datetime, time
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase, override_settings
|
||||||
|
from django.utils import translation
|
||||||
from django.utils.translation import activate, deactivate
|
from django.utils.translation import activate, deactivate
|
||||||
|
|
||||||
|
|
||||||
@override_settings(TIME_INPUT_FORMATS=["%I:%M:%S %p", "%I:%M %p"], USE_L10N=True)
|
|
||||||
class LocalizedTimeTests(SimpleTestCase):
|
class LocalizedTimeTests(SimpleTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
# nl/formats.py has customized TIME_INPUT_FORMATS:
|
# nl/formats.py has customized TIME_INPUT_FORMATS:
|
||||||
|
@ -117,6 +117,7 @@ class LocalizedTimeTests(SimpleTestCase):
|
||||||
self.assertEqual(text, "13:30:00")
|
self.assertEqual(text, "13:30:00")
|
||||||
|
|
||||||
|
|
||||||
|
@translation.override(None) # RemovedInDjango50Warning.
|
||||||
@override_settings(TIME_INPUT_FORMATS=["%I:%M:%S %p", "%I:%M %p"])
|
@override_settings(TIME_INPUT_FORMATS=["%I:%M:%S %p", "%I:%M %p"])
|
||||||
class CustomTimeInputFormatsTests(SimpleTestCase):
|
class CustomTimeInputFormatsTests(SimpleTestCase):
|
||||||
def test_timeField(self):
|
def test_timeField(self):
|
||||||
|
@ -310,7 +311,6 @@ class SimpleTimeFormatTests(SimpleTestCase):
|
||||||
self.assertEqual(text, "13:30:00")
|
self.assertEqual(text, "13:30:00")
|
||||||
|
|
||||||
|
|
||||||
@override_settings(DATE_INPUT_FORMATS=["%d/%m/%Y", "%d-%m-%Y"], USE_L10N=True)
|
|
||||||
class LocalizedDateTests(SimpleTestCase):
|
class LocalizedDateTests(SimpleTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
activate('de')
|
activate('de')
|
||||||
|
@ -422,6 +422,7 @@ class LocalizedDateTests(SimpleTestCase):
|
||||||
self.assertEqual(text, "21.12.2010")
|
self.assertEqual(text, "21.12.2010")
|
||||||
|
|
||||||
|
|
||||||
|
@translation.override(None) # RemovedInDjango50Warning.
|
||||||
@override_settings(DATE_INPUT_FORMATS=["%d.%m.%Y", "%d-%m-%Y"])
|
@override_settings(DATE_INPUT_FORMATS=["%d.%m.%Y", "%d-%m-%Y"])
|
||||||
class CustomDateInputFormatsTests(SimpleTestCase):
|
class CustomDateInputFormatsTests(SimpleTestCase):
|
||||||
def test_dateField(self):
|
def test_dateField(self):
|
||||||
|
@ -615,7 +616,6 @@ class SimpleDateFormatTests(SimpleTestCase):
|
||||||
self.assertEqual(text, "2010-12-21")
|
self.assertEqual(text, "2010-12-21")
|
||||||
|
|
||||||
|
|
||||||
@override_settings(DATETIME_INPUT_FORMATS=["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"], USE_L10N=True)
|
|
||||||
class LocalizedDateTimeTests(SimpleTestCase):
|
class LocalizedDateTimeTests(SimpleTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
activate('de')
|
activate('de')
|
||||||
|
@ -731,6 +731,7 @@ class LocalizedDateTimeTests(SimpleTestCase):
|
||||||
self.assertEqual(text, "21.12.2010 13:30:00")
|
self.assertEqual(text, "21.12.2010 13:30:00")
|
||||||
|
|
||||||
|
|
||||||
|
@translation.override(None) # RemovedInDjango50Warning.
|
||||||
@override_settings(DATETIME_INPUT_FORMATS=["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"])
|
@override_settings(DATETIME_INPUT_FORMATS=["%I:%M:%S %p %d/%m/%Y", "%I:%M %p %d-%m-%Y"])
|
||||||
class CustomDateTimeInputFormatsTests(SimpleTestCase):
|
class CustomDateTimeInputFormatsTests(SimpleTestCase):
|
||||||
def test_dateTimeField(self):
|
def test_dateTimeField(self):
|
||||||
|
|
|
@ -133,7 +133,7 @@ class CheckboxSelectMultipleTest(WidgetTest):
|
||||||
"""
|
"""
|
||||||
self.check_html(widget, 'letters', ['a', 'c'], html=html)
|
self.check_html(widget, 'letters', ['a', 'c'], html=html)
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_doesnt_localize_input_value(self):
|
def test_doesnt_localize_input_value(self):
|
||||||
choices = [
|
choices = [
|
||||||
(1, 'One'),
|
(1, 'One'),
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from django.forms import DateInput
|
from django.forms import DateInput
|
||||||
from django.test import override_settings
|
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
|
||||||
from .base import WidgetTest
|
from .base import WidgetTest
|
||||||
|
@ -38,7 +37,6 @@ class DateInputTest(WidgetTest):
|
||||||
widget = DateInput(format='%d/%m/%Y', attrs={'type': 'date'})
|
widget = DateInput(format='%d/%m/%Y', attrs={'type': 'date'})
|
||||||
self.check_html(widget, 'date', d, html='<input type="date" name="date" value="17/09/2007">')
|
self.check_html(widget, 'date', d, html='<input type="date" name="date" value="17/09/2007">')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('de-at')
|
@translation.override('de-at')
|
||||||
def test_l10n(self):
|
def test_l10n(self):
|
||||||
self.check_html(
|
self.check_html(
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.forms import DateTimeInput
|
from django.forms import DateTimeInput
|
||||||
from django.test import override_settings
|
from django.test import ignore_warnings
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
|
|
||||||
from .base import WidgetTest
|
from .base import WidgetTest
|
||||||
|
|
||||||
|
@ -39,7 +40,6 @@ class DateTimeInputTest(WidgetTest):
|
||||||
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
|
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
|
||||||
self.check_html(widget, 'date', d, html='<input type="datetime" name="date" value="17/09/2007 12:51">')
|
self.check_html(widget, 'date', d, html='<input type="datetime" name="date" value="17/09/2007 12:51">')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('de-at')
|
@translation.override('de-at')
|
||||||
def test_l10n(self):
|
def test_l10n(self):
|
||||||
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
|
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
|
||||||
|
@ -47,15 +47,22 @@ class DateTimeInputTest(WidgetTest):
|
||||||
'<input type="text" name="date" value="17.09.2007 12:51:34">'
|
'<input type="text" name="date" value="17.09.2007 12:51:34">'
|
||||||
))
|
))
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('de-at')
|
@translation.override('de-at')
|
||||||
def test_locale_aware(self):
|
def test_locale_aware(self):
|
||||||
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
|
d = datetime(2007, 9, 17, 12, 51, 34, 482548)
|
||||||
with self.settings(USE_L10N=False):
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
self.check_html(
|
# @ignore_warnings and USE_L10N=False. The assertion should remain
|
||||||
self.widget, 'date', d,
|
# because format-related settings will take precedence over
|
||||||
html='<input type="text" name="date" value="2007-09-17 12:51:34">',
|
# locale-dictated formats.
|
||||||
)
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
with self.settings(USE_L10N=False):
|
||||||
|
with self.settings(DATETIME_INPUT_FORMATS=[
|
||||||
|
'%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M:%S.%f', '%Y-%m-%d %H:%M',
|
||||||
|
]):
|
||||||
|
self.check_html(
|
||||||
|
self.widget, 'date', d,
|
||||||
|
html='<input type="text" name="date" value="2007-09-17 12:51:34">',
|
||||||
|
)
|
||||||
with translation.override('es'):
|
with translation.override('es'):
|
||||||
self.check_html(
|
self.check_html(
|
||||||
self.widget, 'date', d,
|
self.widget, 'date', d,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from django.forms import NullBooleanSelect
|
from django.forms import NullBooleanSelect
|
||||||
from django.test import override_settings
|
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
|
||||||
from .base import WidgetTest
|
from .base import WidgetTest
|
||||||
|
@ -89,7 +88,6 @@ class NullBooleanSelectTest(WidgetTest):
|
||||||
</select>"""
|
</select>"""
|
||||||
))
|
))
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
def test_l10n(self):
|
def test_l10n(self):
|
||||||
"""
|
"""
|
||||||
The NullBooleanSelect widget's options are lazily localized (#17190).
|
The NullBooleanSelect widget's options are lazily localized (#17190).
|
||||||
|
|
|
@ -6,7 +6,7 @@ from .base import WidgetTest
|
||||||
|
|
||||||
class NumberInputTests(WidgetTest):
|
class NumberInputTests(WidgetTest):
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_attrs_not_localized(self):
|
def test_attrs_not_localized(self):
|
||||||
widget = NumberInput(attrs={'max': 12345, 'min': 1234, 'step': 9999})
|
widget = NumberInput(attrs={'max': 12345, 'min': 1234, 'step': 9999})
|
||||||
self.check_html(
|
self.check_html(
|
||||||
|
|
|
@ -101,7 +101,7 @@ class RadioSelectTest(WidgetTest):
|
||||||
"""
|
"""
|
||||||
self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', attrs={'class': 'bar'}, html=html)
|
self.check_html(self.widget(choices=self.beatles), 'beatle', 'J', attrs={'class': 'bar'}, html=html)
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_doesnt_localize_input_value(self):
|
def test_doesnt_localize_input_value(self):
|
||||||
choices = [
|
choices = [
|
||||||
(1, 'One'),
|
(1, 'One'),
|
||||||
|
|
|
@ -220,7 +220,7 @@ class SelectTest(WidgetTest):
|
||||||
</select>"""
|
</select>"""
|
||||||
))
|
))
|
||||||
|
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_doesnt_localize_option_value(self):
|
def test_doesnt_localize_option_value(self):
|
||||||
choices = [
|
choices = [
|
||||||
(1, 'One'),
|
(1, 'One'),
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from datetime import date
|
from datetime import date
|
||||||
|
|
||||||
from django.forms import DateField, Form, SelectDateWidget
|
from django.forms import DateField, Form, SelectDateWidget
|
||||||
from django.test import override_settings
|
from django.test import ignore_warnings, override_settings
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
from django.utils.dates import MONTHS_AP
|
from django.utils.dates import MONTHS_AP
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
|
|
||||||
from .base import WidgetTest
|
from .base import WidgetTest
|
||||||
|
|
||||||
|
@ -387,7 +388,6 @@ class SelectDateWidgetTest(WidgetTest):
|
||||||
with self.assertRaisesMessage(ValueError, 'empty_label list/tuple must have 3 elements.'):
|
with self.assertRaisesMessage(ValueError, 'empty_label list/tuple must have 3 elements.'):
|
||||||
SelectDateWidget(years=('2014',), empty_label=('not enough', 'values'))
|
SelectDateWidget(years=('2014',), empty_label=('not enough', 'values'))
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('nl')
|
@translation.override('nl')
|
||||||
def test_l10n(self):
|
def test_l10n(self):
|
||||||
w = SelectDateWidget(
|
w = SelectDateWidget(
|
||||||
|
@ -485,6 +485,11 @@ class SelectDateWidgetTest(WidgetTest):
|
||||||
'13-08-0001',
|
'13-08-0001',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
|
# @ignore_warnings and USE_L10N=False. The test should remain because
|
||||||
|
# format-related settings will take precedence over locale-dictated
|
||||||
|
# formats.
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
@override_settings(USE_L10N=False, DATE_INPUT_FORMATS=['%d.%m.%Y'])
|
@override_settings(USE_L10N=False, DATE_INPUT_FORMATS=['%d.%m.%Y'])
|
||||||
def test_custom_input_format(self):
|
def test_custom_input_format(self):
|
||||||
w = SelectDateWidget(years=('0001', '1899', '2009', '2010'))
|
w = SelectDateWidget(years=('0001', '1899', '2009', '2010'))
|
||||||
|
@ -551,7 +556,7 @@ class SelectDateWidgetTest(WidgetTest):
|
||||||
data = {'field_day': '1', 'field_month': '12', 'field_year': '2000'}
|
data = {'field_day': '1', 'field_month': '12', 'field_year': '2000'}
|
||||||
self.assertIs(self.widget.value_omitted_from_data(data, {}, 'field'), False)
|
self.assertIs(self.widget.value_omitted_from_data(data, {}, 'field'), False)
|
||||||
|
|
||||||
@override_settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_years_rendered_without_separator(self):
|
def test_years_rendered_without_separator(self):
|
||||||
widget = SelectDateWidget(years=(2007,))
|
widget = SelectDateWidget(years=(2007,))
|
||||||
self.check_html(widget, 'mydate', '', html=(
|
self.check_html(widget, 'mydate', '', html=(
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from django.forms import SplitHiddenDateTimeWidget
|
from django.forms import SplitHiddenDateTimeWidget
|
||||||
from django.test import override_settings
|
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
|
||||||
from .base import WidgetTest
|
from .base import WidgetTest
|
||||||
|
@ -30,7 +29,6 @@ class SplitHiddenDateTimeWidgetTest(WidgetTest):
|
||||||
'<input type="hidden" name="date_1" value="12:51:00">'
|
'<input type="hidden" name="date_1" value="12:51:00">'
|
||||||
))
|
))
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('de-at')
|
@translation.override('de-at')
|
||||||
def test_l10n(self):
|
def test_l10n(self):
|
||||||
d = datetime(2007, 9, 17, 12, 51)
|
d = datetime(2007, 9, 17, 12, 51)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from datetime import time
|
from datetime import time
|
||||||
|
|
||||||
from django.forms import TimeInput
|
from django.forms import TimeInput
|
||||||
from django.test import override_settings
|
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
|
||||||
from .base import WidgetTest
|
from .base import WidgetTest
|
||||||
|
@ -41,7 +40,6 @@ class TimeInputTest(WidgetTest):
|
||||||
widget = TimeInput(format='%H:%M', attrs={'type': 'time'})
|
widget = TimeInput(format='%H:%M', attrs={'type': 'time'})
|
||||||
self.check_html(widget, 'time', t, html='<input type="time" name="time" value="12:51">')
|
self.check_html(widget, 'time', t, html='<input type="time" name="time" value="12:51">')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@translation.override('de-at')
|
@translation.override('de-at')
|
||||||
def test_l10n(self):
|
def test_l10n(self):
|
||||||
t = time(12, 51, 34, 482548)
|
t = time(12, 51, 34, 482548)
|
||||||
|
|
|
@ -238,7 +238,7 @@ class SpecializedFieldTest(SimpleTestCase):
|
||||||
self.assertIn(escape(ogr.json), rendered)
|
self.assertIn(escape(ogr.json), rendered)
|
||||||
|
|
||||||
# map_srid in openlayers.html template must not be localized.
|
# map_srid in openlayers.html template must not be localized.
|
||||||
@override_settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True)
|
@override_settings(USE_THOUSAND_SEPARATOR=True)
|
||||||
def test_pointfield(self):
|
def test_pointfield(self):
|
||||||
class PointForm(forms.Form):
|
class PointForm(forms.Form):
|
||||||
p = forms.PointField()
|
p = forms.PointField()
|
||||||
|
|
|
@ -89,13 +89,13 @@ class HumanizeTests(SimpleTestCase):
|
||||||
'100', '1,000', '10,123', '10,311', '1,000,000', '1,234,567.1234567',
|
'100', '1,000', '10,123', '10,311', '1,000,000', '1,234,567.1234567',
|
||||||
'1,234,567.1234567', None,
|
'1,234,567.1234567', None,
|
||||||
)
|
)
|
||||||
with self.settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=False):
|
with self.settings(USE_THOUSAND_SEPARATOR=False):
|
||||||
with translation.override('en'):
|
with translation.override('en'):
|
||||||
self.humanize_tester(test_list, result_list, 'intcomma')
|
self.humanize_tester(test_list, result_list, 'intcomma')
|
||||||
|
|
||||||
def test_intcomma_without_number_grouping(self):
|
def test_intcomma_without_number_grouping(self):
|
||||||
# Regression for #17414
|
# Regression for #17414
|
||||||
with translation.override('ja'), self.settings(USE_L10N=True):
|
with translation.override('ja'):
|
||||||
self.humanize_tester([100], ['100'], 'intcomma')
|
self.humanize_tester([100], ['100'], 'intcomma')
|
||||||
|
|
||||||
def test_intword(self):
|
def test_intword(self):
|
||||||
|
@ -126,7 +126,7 @@ class HumanizeTests(SimpleTestCase):
|
||||||
'100', '1000', '10123', '10311', '1000000', None)
|
'100', '1000', '10123', '10311', '1000000', None)
|
||||||
result_list = ('100', '1.000', '10.123', '10.311', '1.000.000', '1.234.567,25',
|
result_list = ('100', '1.000', '10.123', '10.311', '1.000.000', '1.234.567,25',
|
||||||
'100', '1.000', '10.123', '10.311', '1.000.000', None)
|
'100', '1.000', '10.123', '10.311', '1.000.000', None)
|
||||||
with self.settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True):
|
with self.settings(USE_THOUSAND_SEPARATOR=True):
|
||||||
with translation.override('de'):
|
with translation.override('de'):
|
||||||
self.humanize_tester(test_list, result_list, 'intcomma')
|
self.humanize_tester(test_list, result_list, 'intcomma')
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ class HumanizeTests(SimpleTestCase):
|
||||||
# Negative integers.
|
# Negative integers.
|
||||||
test_list_negative = ('-' + test for test in test_list_positive)
|
test_list_negative = ('-' + test for test in test_list_positive)
|
||||||
result_list_negative = ('-' + result for result in result_list_positive)
|
result_list_negative = ('-' + result for result in result_list_positive)
|
||||||
with self.settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True):
|
with self.settings(USE_THOUSAND_SEPARATOR=True):
|
||||||
with translation.override('de'):
|
with translation.override('de'):
|
||||||
self.humanize_tester(
|
self.humanize_tester(
|
||||||
(*test_list_positive, *test_list_negative),
|
(*test_list_positive, *test_list_negative),
|
||||||
|
@ -355,7 +355,7 @@ class HumanizeTests(SimpleTestCase):
|
||||||
orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime
|
orig_humanize_datetime, humanize.datetime = humanize.datetime, MockDateTime
|
||||||
try:
|
try:
|
||||||
# Choose a language with different naturaltime-past/naturaltime-future translations
|
# Choose a language with different naturaltime-past/naturaltime-future translations
|
||||||
with translation.override('cs'), self.settings(USE_L10N=True):
|
with translation.override('cs'):
|
||||||
self.humanize_tester(test_list, result_list, 'naturaltime')
|
self.humanize_tester(test_list, result_list, 'naturaltime')
|
||||||
finally:
|
finally:
|
||||||
humanize.datetime = orig_humanize_datetime
|
humanize.datetime = orig_humanize_datetime
|
||||||
|
|
|
@ -19,9 +19,11 @@ from django.conf.locale import LANG_INFO
|
||||||
from django.conf.urls.i18n import i18n_patterns
|
from django.conf.urls.i18n import i18n_patterns
|
||||||
from django.template import Context, Template
|
from django.template import Context, Template
|
||||||
from django.test import (
|
from django.test import (
|
||||||
RequestFactory, SimpleTestCase, TestCase, override_settings,
|
RequestFactory, SimpleTestCase, TestCase, ignore_warnings,
|
||||||
|
override_settings,
|
||||||
)
|
)
|
||||||
from django.utils import translation
|
from django.utils import translation
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
from django.utils.formats import (
|
from django.utils.formats import (
|
||||||
date_format, get_format, iter_format_modules, localize, localize_input,
|
date_format, get_format, iter_format_modules, localize, localize_input,
|
||||||
reset_format_cache, sanitize_separators, sanitize_strftime_format,
|
reset_format_cache, sanitize_separators, sanitize_strftime_format,
|
||||||
|
@ -422,7 +424,6 @@ class TranslationThreadSafetyTests(SimpleTestCase):
|
||||||
self.assertLess(translation_count, len(trans_real._translations))
|
self.assertLess(translation_count, len(trans_real._translations))
|
||||||
|
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
class FormattingTests(SimpleTestCase):
|
class FormattingTests(SimpleTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -498,6 +499,7 @@ class FormattingTests(SimpleTestCase):
|
||||||
self.assertEqual('31.12.2009 в 20:50', Template('{{ dt|date:"d.m.Y в H:i" }}').render(self.ctxt))
|
self.assertEqual('31.12.2009 в 20:50', Template('{{ dt|date:"d.m.Y в H:i" }}').render(self.ctxt))
|
||||||
self.assertEqual('⌚ 10:15', Template('{{ t|time:"⌚ H:i" }}').render(self.ctxt))
|
self.assertEqual('⌚ 10:15', Template('{{ t|time:"⌚ H:i" }}').render(self.ctxt))
|
||||||
|
|
||||||
|
@ignore_warnings(category=RemovedInDjango50Warning)
|
||||||
@override_settings(USE_L10N=False)
|
@override_settings(USE_L10N=False)
|
||||||
def test_l10n_disabled(self):
|
def test_l10n_disabled(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1135,8 +1137,9 @@ class FormattingTests(SimpleTestCase):
|
||||||
self.assertEqual(sanitize_separators('77\xa0777,777'), '77777.777')
|
self.assertEqual(sanitize_separators('77\xa0777,777'), '77777.777')
|
||||||
self.assertEqual(sanitize_separators('12 345'), '12345')
|
self.assertEqual(sanitize_separators('12 345'), '12345')
|
||||||
self.assertEqual(sanitize_separators('77 777,777'), '77777.777')
|
self.assertEqual(sanitize_separators('77 777,777'), '77777.777')
|
||||||
with self.settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=False):
|
with translation.override(None): # RemovedInDjango50Warning
|
||||||
self.assertEqual(sanitize_separators('12\xa0345'), '12\xa0345')
|
with self.settings(USE_THOUSAND_SEPARATOR=True, THOUSAND_SEPARATOR='.'):
|
||||||
|
self.assertEqual(sanitize_separators('12\xa0345'), '12\xa0345')
|
||||||
|
|
||||||
with self.settings(USE_THOUSAND_SEPARATOR=True):
|
with self.settings(USE_THOUSAND_SEPARATOR=True):
|
||||||
with patch_formats(get_language(), THOUSAND_SEPARATOR='.', DECIMAL_SEPARATOR=','):
|
with patch_formats(get_language(), THOUSAND_SEPARATOR='.', DECIMAL_SEPARATOR=','):
|
||||||
|
@ -1144,18 +1147,25 @@ class FormattingTests(SimpleTestCase):
|
||||||
# Suspicion that user entered dot as decimal separator (#22171)
|
# Suspicion that user entered dot as decimal separator (#22171)
|
||||||
self.assertEqual(sanitize_separators('10.10'), '10.10')
|
self.assertEqual(sanitize_separators('10.10'), '10.10')
|
||||||
|
|
||||||
with self.settings(USE_L10N=False, DECIMAL_SEPARATOR=','):
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
self.assertEqual(sanitize_separators('1001,10'), '1001.10')
|
# @ignore_warnings and USE_L10N=False. The assertions should remain
|
||||||
self.assertEqual(sanitize_separators('1001.10'), '1001.10')
|
# because format-related settings will take precedence over
|
||||||
|
# locale-dictated formats.
|
||||||
with self.settings(
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
USE_L10N=False, DECIMAL_SEPARATOR=',', USE_THOUSAND_SEPARATOR=True,
|
with self.settings(USE_L10N=False):
|
||||||
THOUSAND_SEPARATOR='.'
|
with self.settings(DECIMAL_SEPARATOR=','):
|
||||||
):
|
self.assertEqual(sanitize_separators('1001,10'), '1001.10')
|
||||||
self.assertEqual(sanitize_separators('1.001,10'), '1001.10')
|
self.assertEqual(sanitize_separators('1001.10'), '1001.10')
|
||||||
self.assertEqual(sanitize_separators('1001,10'), '1001.10')
|
with self.settings(
|
||||||
self.assertEqual(sanitize_separators('1001.10'), '1001.10')
|
DECIMAL_SEPARATOR=',',
|
||||||
self.assertEqual(sanitize_separators('1,001.10'), '1.001.10') # Invalid output
|
THOUSAND_SEPARATOR='.',
|
||||||
|
USE_THOUSAND_SEPARATOR=True,
|
||||||
|
):
|
||||||
|
self.assertEqual(sanitize_separators('1.001,10'), '1001.10')
|
||||||
|
self.assertEqual(sanitize_separators('1001,10'), '1001.10')
|
||||||
|
self.assertEqual(sanitize_separators('1001.10'), '1001.10')
|
||||||
|
# Invalid output.
|
||||||
|
self.assertEqual(sanitize_separators('1,001.10'), '1.001.10')
|
||||||
|
|
||||||
def test_iter_format_modules(self):
|
def test_iter_format_modules(self):
|
||||||
"""
|
"""
|
||||||
|
@ -1225,10 +1235,21 @@ class FormattingTests(SimpleTestCase):
|
||||||
output3 = '; '.join([expected_localized, expected_unlocalized])
|
output3 = '; '.join([expected_localized, expected_unlocalized])
|
||||||
output4 = '; '.join([expected_unlocalized, expected_localized])
|
output4 = '; '.join([expected_unlocalized, expected_localized])
|
||||||
with translation.override('de', deactivate=True):
|
with translation.override('de', deactivate=True):
|
||||||
with self.settings(USE_L10N=False, USE_THOUSAND_SEPARATOR=True):
|
# RemovedInDjango50Warning: When the deprecation ends, remove
|
||||||
self.assertEqual(template1.render(context), output1)
|
# @ignore_warnings and USE_L10N=False. The assertions should remain
|
||||||
self.assertEqual(template4.render(context), output4)
|
# because format-related settings will take precedence over
|
||||||
with self.settings(USE_L10N=True, USE_THOUSAND_SEPARATOR=True):
|
# locale-dictated formats.
|
||||||
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
with self.settings(
|
||||||
|
USE_L10N=False,
|
||||||
|
DATE_FORMAT='N j, Y',
|
||||||
|
DECIMAL_SEPARATOR='.',
|
||||||
|
NUMBER_GROUPING=0,
|
||||||
|
USE_THOUSAND_SEPARATOR=True,
|
||||||
|
):
|
||||||
|
self.assertEqual(template1.render(context), output1)
|
||||||
|
self.assertEqual(template4.render(context), output4)
|
||||||
|
with self.settings(USE_THOUSAND_SEPARATOR=True):
|
||||||
self.assertEqual(template1.render(context), output1)
|
self.assertEqual(template1.render(context), output1)
|
||||||
self.assertEqual(template2.render(context), output2)
|
self.assertEqual(template2.render(context), output2)
|
||||||
self.assertEqual(template3.render(context), output3)
|
self.assertEqual(template3.render(context), output3)
|
||||||
|
@ -1242,9 +1263,17 @@ class FormattingTests(SimpleTestCase):
|
||||||
context = Context(
|
context = Context(
|
||||||
{'int': 1455, 'float': 3.14, 'decimal': decimal.Decimal('24.1567')}
|
{'int': 1455, 'float': 3.14, 'decimal': decimal.Decimal('24.1567')}
|
||||||
)
|
)
|
||||||
for use_l10n in [True, False]:
|
with self.settings(
|
||||||
with self.subTest(use_l10n=use_l10n), self.settings(
|
DECIMAL_SEPARATOR=',',
|
||||||
USE_L10N=use_l10n,
|
USE_THOUSAND_SEPARATOR=True,
|
||||||
|
THOUSAND_SEPARATOR='°',
|
||||||
|
NUMBER_GROUPING=2,
|
||||||
|
):
|
||||||
|
self.assertEqual(template.render(context), '1455/3.14/24.1567')
|
||||||
|
# RemovedInDjango50Warning.
|
||||||
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
with self.settings(
|
||||||
|
USE_L10N=False,
|
||||||
DECIMAL_SEPARATOR=',',
|
DECIMAL_SEPARATOR=',',
|
||||||
USE_THOUSAND_SEPARATOR=True,
|
USE_THOUSAND_SEPARATOR=True,
|
||||||
THOUSAND_SEPARATOR='°',
|
THOUSAND_SEPARATOR='°',
|
||||||
|
|
|
@ -248,19 +248,19 @@ class SettingsTests(SimpleTestCase):
|
||||||
Allow deletion of a setting in an overridden settings set (#18824)
|
Allow deletion of a setting in an overridden settings set (#18824)
|
||||||
"""
|
"""
|
||||||
previous_i18n = settings.USE_I18N
|
previous_i18n = settings.USE_I18N
|
||||||
previous_l10n = settings.USE_L10N
|
previous_tz = settings.USE_TZ
|
||||||
with self.settings(USE_I18N=False):
|
with self.settings(USE_I18N=False):
|
||||||
del settings.USE_I18N
|
del settings.USE_I18N
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
getattr(settings, 'USE_I18N')
|
getattr(settings, 'USE_I18N')
|
||||||
# Should also work for a non-overridden setting
|
# Should also work for a non-overridden setting
|
||||||
del settings.USE_L10N
|
del settings.USE_TZ
|
||||||
with self.assertRaises(AttributeError):
|
with self.assertRaises(AttributeError):
|
||||||
getattr(settings, 'USE_L10N')
|
getattr(settings, 'USE_TZ')
|
||||||
self.assertNotIn('USE_I18N', dir(settings))
|
self.assertNotIn('USE_I18N', dir(settings))
|
||||||
self.assertNotIn('USE_L10N', dir(settings))
|
self.assertNotIn('USE_TZ', dir(settings))
|
||||||
self.assertEqual(settings.USE_I18N, previous_i18n)
|
self.assertEqual(settings.USE_I18N, previous_i18n)
|
||||||
self.assertEqual(settings.USE_L10N, previous_l10n)
|
self.assertEqual(settings.USE_TZ, previous_tz)
|
||||||
|
|
||||||
def test_override_settings_nested(self):
|
def test_override_settings_nested(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -176,7 +176,7 @@ class HTTPSitemapTests(SitemapTestsBase):
|
||||||
response = self.client.get('/lastmod-sitemaps/descending.xml')
|
response = self.client.get('/lastmod-sitemaps/descending.xml')
|
||||||
self.assertEqual(response.headers['Last-Modified'], 'Sat, 20 Apr 2013 05:00:00 GMT')
|
self.assertEqual(response.headers['Last-Modified'], 'Sat, 20 Apr 2013 05:00:00 GMT')
|
||||||
|
|
||||||
@override_settings(USE_I18N=True, USE_L10N=True)
|
@override_settings(USE_I18N=True)
|
||||||
def test_localized_priority(self):
|
def test_localized_priority(self):
|
||||||
"""The priority value should not be localized."""
|
"""The priority value should not be localized."""
|
||||||
with translation.override('fr'):
|
with translation.override('fr'):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import datetime, time
|
from datetime import datetime, time
|
||||||
|
|
||||||
from django.template.defaultfilters import date
|
from django.template.defaultfilters import date
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase
|
||||||
from django.utils import timezone, translation
|
from django.utils import timezone, translation
|
||||||
|
|
||||||
from ..utils import setup
|
from ..utils import setup
|
||||||
|
@ -20,13 +20,9 @@ class DateTests(TimezoneTestCase):
|
||||||
output = self.engine.render_to_string('date02', {'d': datetime(2008, 1, 1)})
|
output = self.engine.render_to_string('date02', {'d': datetime(2008, 1, 1)})
|
||||||
self.assertEqual(output, 'Jan. 1, 2008')
|
self.assertEqual(output, 'Jan. 1, 2008')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@setup({'date02_l10n': '{{ d|date }}'})
|
@setup({'date02_l10n': '{{ d|date }}'})
|
||||||
def test_date02_l10n(self):
|
def test_date02_l10n(self):
|
||||||
"""
|
"""Without arg, the active language's DATE_FORMAT is used."""
|
||||||
Without arg and when USE_L10N is True, the active language's DATE_FORMAT
|
|
||||||
is used.
|
|
||||||
"""
|
|
||||||
with translation.override('fr'):
|
with translation.override('fr'):
|
||||||
output = self.engine.render_to_string('date02_l10n', {'d': datetime(2008, 1, 1)})
|
output = self.engine.render_to_string('date02_l10n', {'d': datetime(2008, 1, 1)})
|
||||||
self.assertEqual(output, '1 janvier 2008')
|
self.assertEqual(output, '1 janvier 2008')
|
||||||
|
|
|
@ -47,7 +47,7 @@ class FunctionTests(SimpleTestCase):
|
||||||
('', '0\xa0Bytes'),
|
('', '0\xa0Bytes'),
|
||||||
('\N{GREEK SMALL LETTER ALPHA}', '0\xa0Bytes'),
|
('\N{GREEK SMALL LETTER ALPHA}', '0\xa0Bytes'),
|
||||||
]
|
]
|
||||||
with self.settings(USE_L10N=True), translation.override('de'):
|
with translation.override('de'):
|
||||||
for value, expected in tests:
|
for value, expected in tests:
|
||||||
with self.subTest(value=value):
|
with self.subTest(value=value):
|
||||||
self.assertEqual(filesizeformat(value), expected)
|
self.assertEqual(filesizeformat(value), expected)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from datetime import time
|
from datetime import time
|
||||||
|
|
||||||
from django.template.defaultfilters import time as time_filter
|
from django.template.defaultfilters import time as time_filter
|
||||||
from django.test import SimpleTestCase, override_settings
|
from django.test import SimpleTestCase
|
||||||
from django.utils import timezone, translation
|
from django.utils import timezone, translation
|
||||||
|
|
||||||
from ..utils import setup
|
from ..utils import setup
|
||||||
|
@ -18,7 +18,6 @@ class TimeTests(TimezoneTestCase):
|
||||||
output = self.engine.render_to_string('time00', {'dt': time(16, 25)})
|
output = self.engine.render_to_string('time00', {'dt': time(16, 25)})
|
||||||
self.assertEqual(output, '4:25 p.m.')
|
self.assertEqual(output, '4:25 p.m.')
|
||||||
|
|
||||||
@override_settings(USE_L10N=True)
|
|
||||||
@setup({'time00_l10n': '{{ dt|time }}'})
|
@setup({'time00_l10n': '{{ dt|time }}'})
|
||||||
def test_time00_l10n(self):
|
def test_time00_l10n(self):
|
||||||
with translation.override('fr'):
|
with translation.override('fr'):
|
||||||
|
|
|
@ -24,12 +24,13 @@ from django.template import (
|
||||||
Context, RequestContext, Template, TemplateSyntaxError, context_processors,
|
Context, RequestContext, Template, TemplateSyntaxError, context_processors,
|
||||||
)
|
)
|
||||||
from django.test import (
|
from django.test import (
|
||||||
SimpleTestCase, TestCase, TransactionTestCase, override_settings,
|
SimpleTestCase, TestCase, TransactionTestCase, ignore_warnings,
|
||||||
skipIfDBFeature, skipUnlessDBFeature,
|
override_settings, skipIfDBFeature, skipUnlessDBFeature,
|
||||||
)
|
)
|
||||||
from django.test.utils import requires_tz_support
|
from django.test.utils import requires_tz_support
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
from django.utils.deprecation import RemovedInDjango50Warning
|
||||||
from django.utils.timezone import timedelta
|
from django.utils.timezone import timedelta
|
||||||
|
|
||||||
from .forms import (
|
from .forms import (
|
||||||
|
@ -812,8 +813,15 @@ class SerializationTests(SimpleTestCase):
|
||||||
self.assertEqual(obj.dt, dt)
|
self.assertEqual(obj.dt, dt)
|
||||||
|
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove setUpClass() and
|
||||||
|
# USE_L10N=False. The tests should remain because format-related settings will
|
||||||
|
# take precedence over locale-dictated formats.
|
||||||
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
|
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
|
||||||
class TemplateTests(SimpleTestCase):
|
class TemplateTests(SimpleTestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
super().setUpClass()
|
||||||
|
|
||||||
@requires_tz_support
|
@requires_tz_support
|
||||||
def test_localtime_templatetag_and_filters(self):
|
def test_localtime_templatetag_and_filters(self):
|
||||||
|
@ -1072,8 +1080,15 @@ class TemplateTests(SimpleTestCase):
|
||||||
self.assertEqual(tpl.render(Context({})), "+0700")
|
self.assertEqual(tpl.render(Context({})), "+0700")
|
||||||
|
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove setUpClass() and
|
||||||
|
# USE_L10N=False. The tests should remain because format-related settings will
|
||||||
|
# take precedence over locale-dictated formats.
|
||||||
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=False)
|
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=False)
|
||||||
class LegacyFormsTests(TestCase):
|
class LegacyFormsTests(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
super().setUpClass()
|
||||||
|
|
||||||
def test_form(self):
|
def test_form(self):
|
||||||
form = EventForm({'dt': '2011-09-01 13:20:30'})
|
form = EventForm({'dt': '2011-09-01 13:20:30'})
|
||||||
|
@ -1109,8 +1124,15 @@ class LegacyFormsTests(TestCase):
|
||||||
self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 13, 20, 30))
|
self.assertEqual(e.dt, datetime.datetime(2011, 9, 1, 13, 20, 30))
|
||||||
|
|
||||||
|
|
||||||
|
# RemovedInDjango50Warning: When the deprecation ends, remove setUpClass() and
|
||||||
|
# USE_L10N=False. The tests should remain because format-related settings will
|
||||||
|
# take precedence over locale-dictated formats.
|
||||||
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
|
@override_settings(DATETIME_FORMAT='c', TIME_ZONE='Africa/Nairobi', USE_L10N=False, USE_TZ=True)
|
||||||
class NewFormsTests(TestCase):
|
class NewFormsTests(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
super().setUpClass()
|
||||||
|
|
||||||
@requires_tz_support
|
@requires_tz_support
|
||||||
def test_form(self):
|
def test_form(self):
|
||||||
|
@ -1183,6 +1205,10 @@ class NewFormsTests(TestCase):
|
||||||
ROOT_URLCONF='timezones.urls',
|
ROOT_URLCONF='timezones.urls',
|
||||||
)
|
)
|
||||||
class AdminTests(TestCase):
|
class AdminTests(TestCase):
|
||||||
|
@classmethod
|
||||||
|
def setUpClass(cls):
|
||||||
|
with ignore_warnings(category=RemovedInDjango50Warning):
|
||||||
|
super().setUpClass()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpTestData(cls):
|
def setUpTestData(cls):
|
||||||
|
|
|
@ -15,9 +15,8 @@ class TestNumberFormat(SimpleTestCase):
|
||||||
self.assertEqual(nformat(1234, '.', grouping=2, thousand_sep=',', force_grouping=True), '12,34')
|
self.assertEqual(nformat(1234, '.', grouping=2, thousand_sep=',', force_grouping=True), '12,34')
|
||||||
self.assertEqual(nformat(-1234.33, '.', decimal_pos=1), '-1234.3')
|
self.assertEqual(nformat(-1234.33, '.', decimal_pos=1), '-1234.3')
|
||||||
# The use_l10n parameter can force thousand grouping behavior.
|
# The use_l10n parameter can force thousand grouping behavior.
|
||||||
with self.settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=True):
|
with self.settings(USE_THOUSAND_SEPARATOR=True):
|
||||||
self.assertEqual(nformat(1234, '.', grouping=3, thousand_sep=',', use_l10n=False), '1234')
|
self.assertEqual(nformat(1234, '.', grouping=3, thousand_sep=',', use_l10n=False), '1234')
|
||||||
with self.settings(USE_THOUSAND_SEPARATOR=True, USE_L10N=False):
|
|
||||||
self.assertEqual(nformat(1234, '.', grouping=3, thousand_sep=',', use_l10n=True), '1,234')
|
self.assertEqual(nformat(1234, '.', grouping=3, thousand_sep=',', use_l10n=True), '1,234')
|
||||||
|
|
||||||
def test_format_string(self):
|
def test_format_string(self):
|
||||||
|
|
|
@ -195,7 +195,7 @@ class DebugViewTests(SimpleTestCase):
|
||||||
"""
|
"""
|
||||||
Numeric IDs and fancy traceback context blocks line numbers shouldn't be localized.
|
Numeric IDs and fancy traceback context blocks line numbers shouldn't be localized.
|
||||||
"""
|
"""
|
||||||
with self.settings(DEBUG=True, USE_L10N=True):
|
with self.settings(DEBUG=True):
|
||||||
with self.assertLogs('django.request', 'ERROR'):
|
with self.assertLogs('django.request', 'ERROR'):
|
||||||
response = self.client.get('/raises500/')
|
response = self.client.get('/raises500/')
|
||||||
# We look for a HTML fragment of the form
|
# We look for a HTML fragment of the form
|
||||||
|
|
|
@ -206,8 +206,8 @@ class I18NViewTests(SimpleTestCase):
|
||||||
def test_get_formats(self):
|
def test_get_formats(self):
|
||||||
formats = get_formats()
|
formats = get_formats()
|
||||||
# Test 3 possible types in get_formats: integer, string, and list.
|
# Test 3 possible types in get_formats: integer, string, and list.
|
||||||
self.assertEqual(formats['FIRST_DAY_OF_WEEK'], 0)
|
self.assertEqual(formats['FIRST_DAY_OF_WEEK'], 1)
|
||||||
self.assertEqual(formats['DECIMAL_SEPARATOR'], '.')
|
self.assertEqual(formats['DECIMAL_SEPARATOR'], ',')
|
||||||
self.assertEqual(formats['TIME_INPUT_FORMATS'], ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'])
|
self.assertEqual(formats['TIME_INPUT_FORMATS'], ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'])
|
||||||
|
|
||||||
def test_jsi18n(self):
|
def test_jsi18n(self):
|
||||||
|
@ -243,7 +243,7 @@ class I18NViewTests(SimpleTestCase):
|
||||||
self.assertIn('catalog', data)
|
self.assertIn('catalog', data)
|
||||||
self.assertIn('formats', data)
|
self.assertIn('formats', data)
|
||||||
self.assertEqual(data['formats']['TIME_INPUT_FORMATS'], ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'])
|
self.assertEqual(data['formats']['TIME_INPUT_FORMATS'], ['%H:%M:%S', '%H:%M:%S.%f', '%H:%M'])
|
||||||
self.assertEqual(data['formats']['FIRST_DAY_OF_WEEK'], 0)
|
self.assertEqual(data['formats']['FIRST_DAY_OF_WEEK'], 1)
|
||||||
self.assertIn('plural', data)
|
self.assertIn('plural', data)
|
||||||
self.assertEqual(data['catalog']['month name\x04May'], 'Mai')
|
self.assertEqual(data['catalog']['month name\x04May'], 'Mai')
|
||||||
self.assertIn('DATETIME_FORMAT', data['formats'])
|
self.assertIn('DATETIME_FORMAT', data['formats'])
|
||||||
|
|
Loading…
Reference in New Issue