diff --git a/modeltranslation/management/commands/sync_translation_fields.py b/modeltranslation/management/commands/sync_translation_fields.py index b993817..f1b0f13 100644 --- a/modeltranslation/management/commands/sync_translation_fields.py +++ b/modeltranslation/management/commands/sync_translation_fields.py @@ -10,12 +10,11 @@ You will need to execute this command in two cases: Credits: Heavily inspired by django-transmeta's sync_transmeta_db command. """ from django.conf import settings -from django.core.management.base import BaseCommand +from django.core.management.base import NoArgsCommand from django.core.management.color import no_style from django.db import connection, transaction -from django.db.models import get_models -from modeltranslation.translator import translator, NotRegistered +from modeltranslation.translator import translator from modeltranslation.utils import build_localized_fieldname @@ -41,46 +40,38 @@ def print_missing_langs(missing_langs, field_name, model_name): field_name, model_name, ", ".join(missing_langs)) -class Command(BaseCommand): - help = 'Detect new translatable fields or new available languages and sync database structure' +class Command(NoArgsCommand): + help = ('Detect new translatable fields or new available languages and' + ' sync database structure. Does not remove columns of removed' + ' languages or undeclared fields.') - def handle(self, *args, **options): + def handle_noargs(self, **options): """ Command execution. """ self.cursor = connection.cursor() self.introspection = connection.introspection - all_models = get_models() found_missing_fields = False - for model in all_models: - try: - options = translator.get_options_for_model(model) - # Options returns full-wide spectrum of localized fields but - # we only want to synchronize the local fields attached to the - # model. - local_field_names = [field.name for field in model._meta.local_fields] - translatable_fields = [field for field in options.localized_fieldnames - if field in local_field_names] - model_full_name = '%s.%s' % (model._meta.app_label, model._meta.module_name) - db_table = model._meta.db_table - for field_name in translatable_fields: - missing_langs = list( - self.get_missing_languages(field_name, db_table)) - if missing_langs: - found_missing_fields = True - print_missing_langs(missing_langs, field_name, model_full_name) - sql_sentences = self.get_sync_sql(field_name, missing_langs, model) - execute_sql = ask_for_confirmation(sql_sentences, model_full_name) - if execute_sql: - print 'Executing SQL...', - for sentence in sql_sentences: - self.cursor.execute(sentence) - print 'Done' - else: - print 'SQL not executed' - except NotRegistered: - pass + models = translator.get_registered_models(abstract=False) + for model in models: + db_table = model._meta.db_table + model_full_name = '%s.%s' % (model._meta.app_label, model._meta.module_name) + opts = translator.get_options_for_model(model) + for field_name in opts.local_fields.iterkeys(): + missing_langs = list(self.get_missing_languages(field_name, db_table)) + if missing_langs: + found_missing_fields = True + print_missing_langs(missing_langs, field_name, model_full_name) + sql_sentences = self.get_sync_sql(field_name, missing_langs, model) + execute_sql = ask_for_confirmation(sql_sentences, model_full_name) + if execute_sql: + print 'Executing SQL...', + for sentence in sql_sentences: + self.cursor.execute(sentence) + print 'Done' + else: + print 'SQL not executed' transaction.commit_unless_managed() diff --git a/modeltranslation/management/commands/update_translation_fields.py b/modeltranslation/management/commands/update_translation_fields.py index 55601c2..8911292 100644 --- a/modeltranslation/management/commands/update_translation_fields.py +++ b/modeltranslation/management/commands/update_translation_fields.py @@ -8,25 +8,26 @@ from modeltranslation.utils import build_localized_fieldname class Command(NoArgsCommand): - help = ('Updates the default translation fields of all or the specified ' - 'translated application using the value of the original field.') + help = ('Updates empty values of default translation fields using' + ' values from original fields (in all translated models).') - def handle(self, **options): + def handle_noargs(self, **options): verbosity = int(options['verbosity']) if verbosity > 0: self.stdout.write("Using default language: %s\n" % DEFAULT_LANGUAGE) - for model, trans_opts in translator._registry.items(): - if model._meta.abstract: - continue + models = translator.get_registered_models(abstract=False) + for model in models: if verbosity > 0: self.stdout.write("Updating data of model '%s'\n" % model) - for fieldname in trans_opts.fields: - def_lang_fieldname = build_localized_fieldname(fieldname, DEFAULT_LANGUAGE) + opts = translator.get_options_for_model(model) + for field_name in opts.fields.iterkeys(): + def_lang_fieldname = build_localized_fieldname(field_name, DEFAULT_LANGUAGE) # We'll only update fields which do not have an existing value q = Q(**{def_lang_fieldname: None}) - field = model._meta.get_field(fieldname) + field = model._meta.get_field(field_name) if field.empty_strings_allowed: q |= Q(**{def_lang_fieldname: ""}) - model.objects.filter(q).rewrite(False).update(**{def_lang_fieldname: F(fieldname)}) + model.objects.filter(q).rewrite(False).update( + **{def_lang_fieldname: F(field_name)}) diff --git a/modeltranslation/models.py b/modeltranslation/models.py index 7e91c91..72c5e9c 100644 --- a/modeltranslation/models.py +++ b/modeltranslation/models.py @@ -39,14 +39,15 @@ def autodiscover(): import_module(module) # In debug mode, print a list of registered models and pid to stdout. - # Note: Differing model order is fine, _registry is just a dict and we - # don't rely on a particular order. + # Note: Differing model order is fine, we don't rely on a particular + # order, as far as base classes are registered before subclasses. if DEBUG: try: if sys.argv[1] in ('runserver', 'runserver_plus'): - translated_model_names = ', '.join(t.__name__ for t in translator._registry.keys()) - print('modeltranslation: Registered %d models for translation (%s) [pid:%d].' % ( - len(translator._registry), translated_model_names, os.getpid())) + models = translator.get_registered_models() + names = ', '.join(m.__name__ for m in models) + print('modeltranslation: Registered %d models for translation' + ' (%s) [pid: %d].' % (len(models), names, os.getpid())) except IndexError: pass