Fixed #24073 -- Deactivated translations when leave_locale_alone is False

Thanks Tim Graham and Markus Holtermann for the reviews.
This commit is contained in:
Claude Paroz 2015-01-03 20:27:18 +01:00
parent 2c0f64b5f6
commit f7c287fca9
4 changed files with 31 additions and 18 deletions

View File

@ -205,21 +205,20 @@ class BaseCommand(object):
``leave_locale_alone``
A boolean indicating whether the locale set in settings should be
preserved during the execution of the command instead of being
forcibly set to 'en-us'.
preserved during the execution of the command instead of translations
being deactivated.
Default value is ``False``.
Make sure you know what you are doing if you decide to change the value
of this option in your custom command if it creates database content
that is locale-sensitive and such content shouldn't contain any
translations (like it happens e.g. with django.contrim.auth
permissions) as making the locale differ from the de facto default
'en-us' might cause unintended effects.
translations (like it happens e.g. with django.contrib.auth
permissions) as activating any locale might cause unintended effects.
This option can't be False when the can_import_settings option is set
to False too because attempting to set the locale needs access to
settings. This condition will generate a CommandError.
to False too because attempting to deactivate translations needs access
to settings. This condition will generate a CommandError.
"""
# Metadata about this command.
option_list = ()
@ -430,12 +429,12 @@ class BaseCommand(object):
"(%s) and 'can_import_settings' (%s) command "
"options." % (self.leave_locale_alone,
self.can_import_settings))
# Switch to US English, because django-admin creates database
# Deactivate translations, because django-admin creates database
# content like permissions, and those shouldn't contain any
# translations.
from django.utils import translation
saved_locale = translation.get_language()
translation.activate('en-us')
translation.deactivate_all()
try:
if (self.requires_system_checks and

View File

@ -145,13 +145,18 @@ default options such as :djadminopt:`--verbosity` and :djadminopt:`--traceback`.
Management commands and locales
===============================
By default, the :meth:`BaseCommand.execute` method sets the hardcoded 'en-us'
locale because some commands shipped with Django perform several tasks
(for example, user-facing content rendering and database population) that
require a system-neutral string language (for which we use 'en-us').
By default, the :meth:`BaseCommand.execute` method deactivates translations
because some commands shipped with Django perform several tasks (for example,
user-facing content rendering and database population) that require a
project-neutral string language.
If, for some reason, your custom management command needs to use a fixed locale
different from 'en-us', you should manually activate and deactivate it in your
.. versionchanged:: 1.8
In previous versions, Django forced the "en-us" locale instead of
deactivating translations.
If, for some reason, your custom management command needs to use a fixed locale,
you should manually activate and deactivate it in your
:meth:`~BaseCommand.handle` method using the functions provided by the I18N
support code::
@ -177,7 +182,7 @@ support code::
translation.deactivate()
Another need might be that your command simply should use the locale set in
settings and Django should be kept from forcing it to 'en-us'. You can achieve
settings and Django should be kept from deactivating it. You can achieve
it by using the :data:`BaseCommand.leave_locale_alone` option.
When working on the scenarios described above though, take into account that
@ -187,7 +192,7 @@ non-uniform locales, so you might need to:
* Make sure the :setting:`USE_I18N` setting is always ``True`` when running
the command (this is a good example of the potential problems stemming
from a dynamic runtime environment that Django commands avoid offhand by
always using a fixed locale).
deactivating translations).
* Review the code of your command and the code it calls for behavioral
differences when locales are changed and evaluate its impact on

View File

@ -1014,6 +1014,13 @@ Miscellaneous
that Django includes) will no longer convert null values back to an empty
string. This is consistent with other backends.
* When the :attr:`~django.core.management.BaseCommand.leave_locale_alone`
attribute is ``False``, translations are now deactivated instead of forcing
the "en-us" locale. In the case your models contained non-English strings and
you counted on English translations to be activated in management commands,
this will not happen any longer. It might be that new database migrations are
generated (once) after migrating to 1.8.
.. _deprecated-features-1.8:
Features deprecated in 1.8

View File

@ -2,6 +2,7 @@ import os
from django.apps import apps
from django.db import connection
from django.conf import settings
from django.core import management
from django.core.management import BaseCommand, CommandError, find_commands
from django.core.management.utils import find_command, popen_wrapper
@ -52,7 +53,8 @@ class CommandTests(SimpleTestCase):
out = StringIO()
with translation.override('pl'):
management.call_command('leave_locale_alone_false', stdout=out)
self.assertEqual(out.getvalue(), "en-us\n")
# get_language returns settings.LANGUAGE_CODE for NullTranslations instances
self.assertEqual(out.getvalue(), "%s\n" % settings.LANGUAGE_CODE)
def test_configured_locale_preserved(self):
# Leaves locale from settings when set to false