diff --git a/docs/modeltranslation/commands.rst b/docs/modeltranslation/commands.rst index fe76dec..4a59570 100644 --- a/docs/modeltranslation/commands.rst +++ b/docs/modeltranslation/commands.rst @@ -23,10 +23,14 @@ command: $ python manage.py update_translation_fields Taken the news example used throughout the documentation this command will copy -the value from the news object's ``title`` field to the default translation -field ``title_de``. It only does so if the default translation field is empty +the value from the news object's ``title`` field to the translation +field ``title_de``. It only does so if the translation field is empty otherwise nothing is copied. +On default, only the *default language* will have its translation field populated, +but you can provide a ``--language`` option to specify any other language listed +in ``settings.py``. + .. note:: Unless you configured modeltranslation to diff --git a/modeltranslation/management/commands/update_translation_fields.py b/modeltranslation/management/commands/update_translation_fields.py index cd32e16..6b71346 100644 --- a/modeltranslation/management/commands/update_translation_fields.py +++ b/modeltranslation/management/commands/update_translation_fields.py @@ -1,14 +1,17 @@ # -*- coding: utf-8 -*- from django.db.models import F, Q -from django.core.management.base import BaseCommand +from django.core.management.base import BaseCommand, CommandError -from modeltranslation.settings import DEFAULT_LANGUAGE +from modeltranslation.settings import AVAILABLE_LANGUAGES, DEFAULT_LANGUAGE from modeltranslation.translator import translator from modeltranslation.utils import build_localized_fieldname +COMMASPACE = ", " + + class Command(BaseCommand): - help = ('Updates empty values of default translation fields using' + help = ('Updates empty values of translation fields using' ' values from original fields (in all translated models).') def add_arguments(self, parser): @@ -20,6 +23,12 @@ class Command(BaseCommand): 'model_name', nargs='?', help='Model name to update empty values of only this model.', ) + parser.add_argument( + '--language', + action='store', + help=('Language translation field the be updated.' + ' Default language field if not provided') + ) def handle(self, *args, **options): verbosity = options['verbosity'] @@ -41,6 +50,17 @@ class Command(BaseCommand): model_name = model_name.lower() models = [m for m in models if m._meta.model_name == model_name] + # optionally defining the translation field language + lang = options.get('language') or DEFAULT_LANGUAGE + if lang not in AVAILABLE_LANGUAGES: + raise CommandError( + "Cannot find language '%s'. Options are %s." % ( + lang, COMMASPACE.join(AVAILABLE_LANGUAGES) + ) + ) + else: + lang = lang.replace('-', '_') + if verbosity > 0: self.stdout.write("Working on models: %s" % ', '.join([ "{app_label}.{object_name}".format(**m._meta.__dict__) @@ -53,7 +73,7 @@ class Command(BaseCommand): opts = translator.get_options_for_model(model) for field_name in opts.fields.keys(): - def_lang_fieldname = build_localized_fieldname(field_name, DEFAULT_LANGUAGE) + def_lang_fieldname = build_localized_fieldname(field_name, lang) # We'll only update fields which do not have an existing value q = Q(**{def_lang_fieldname: None}) diff --git a/modeltranslation/tests/tests.py b/modeltranslation/tests/tests.py index b1cb3c5..f65a6b9 100644 --- a/modeltranslation/tests/tests.py +++ b/modeltranslation/tests/tests.py @@ -17,6 +17,7 @@ from django.core.exceptions import ValidationError, ImproperlyConfigured from django.core.files.base import ContentFile from django.core.files.storage import default_storage from django.core.management import call_command +from django.core.management.base import CommandError from django.db import IntegrityError from django.db.models import Q, F, Count, TextField from django.test import TestCase, TransactionTestCase @@ -2024,6 +2025,24 @@ class UpdateCommandTest(ModeltranslationTestBase): self.assertEqual('initial', obj1.title_de) self.assertEqual('already', obj2.title_de) + def test_update_command_language_param(self): + trans_real.activate('en') + pk1 = models.TestModel.objects.create(title_en='').pk + pk2 = models.TestModel.objects.create(title_en='already').pk + # Due to ``rewrite(False)`` here, original field will be affected. + models.TestModel.objects.all().rewrite(False).update(title='initial') + + call_command('update_translation_fields', language='en', verbosity=0) + + obj1 = models.TestModel.objects.get(pk=pk1) + obj2 = models.TestModel.objects.get(pk=pk2) + self.assertEqual('initial', obj1.title_en) + self.assertEqual('already', obj2.title_en) + + def test_update_command_invalid_language_param(self): + with self.assertRaises(CommandError): + call_command('update_translation_fields', language='xx', verbosity=0) + class TranslationAdminTest(ModeltranslationTestBase): def setUp(self):