From f7c287fca9c9e6370cc88d1457d3ed9466703687 Mon Sep 17 00:00:00 2001 From: Claude Paroz Date: Sat, 3 Jan 2015 20:27:18 +0100 Subject: [PATCH] Fixed #24073 -- Deactivated translations when leave_locale_alone is False Thanks Tim Graham and Markus Holtermann for the reviews. --- django/core/management/base.py | 17 ++++++++--------- docs/howto/custom-management-commands.txt | 21 +++++++++++++-------- docs/releases/1.8.txt | 7 +++++++ tests/user_commands/tests.py | 4 +++- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/django/core/management/base.py b/django/core/management/base.py index 869a11bce9..930e14192f 100644 --- a/django/core/management/base.py +++ b/django/core/management/base.py @@ -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 diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt index c9695003a1..cab7ea47ac 100644 --- a/docs/howto/custom-management-commands.txt +++ b/docs/howto/custom-management-commands.txt @@ -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 diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 1e0203bdc3..0147b8b67b 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -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 diff --git a/tests/user_commands/tests.py b/tests/user_commands/tests.py index dff7dcaed5..c364b868a3 100644 --- a/tests/user_commands/tests.py +++ b/tests/user_commands/tests.py @@ -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