Commit f7c287fc authored by Claude Paroz's avatar Claude Paroz
Browse files

Fixed #24073 -- Deactivated translations when leave_locale_alone is False

Thanks Tim Graham and Markus Holtermann for the reviews.
parent 2c0f64b5
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -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
+13 −8
Original line number Diff line number Diff line
@@ -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
+7 −0
Original line number Diff line number Diff line
@@ -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
+3 −1
Original line number Diff line number Diff line
@@ -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