def test_get_translation(self): # no translation loaded obj = Normal.objects.untranslated().get(pk=self.normal_id[1]) with self.assertNumQueries(1): translation = get_translation(obj, 'ja') self.assertEqual(translation.language_code, 'ja') self.assertEqual(translation.translated_field, NORMAL[1].translated_field['ja']) # translation loaded (it should be ignored) obj = Normal.objects.language('en').get(pk=self.normal_id[1]) obj.translated_field = 'changed' with self.assertNumQueries(1): translation = get_translation(obj, 'en') self.assertEqual(translation.language_code, 'en') self.assertEqual(translation.translated_field, NORMAL[1].translated_field['en']) # with prefetching obj = Normal.objects.untranslated().prefetch_related('translations').get(pk=self.normal_id[1]) with self.assertNumQueries(0): translation = get_translation(obj, 'ja') self.assertEqual(translation.language_code, 'ja') self.assertEqual(translation.translated_field, NORMAL[1].translated_field['ja']) # with prefetching and non-existent translation with self.assertNumQueries(0): self.assertRaises(Normal.DoesNotExist, get_translation, obj, 'xx')
def save(self, commit=True): if self.instance.pk is None: fail_message = 'created' new = True else: fail_message = 'changed' new = False if self.errors: opts = self.instance._meta raise ValueError("The %s could not be %s because the data didn't" " validate." % (opts.object_name, fail_message)) trans_model = self.instance._meta.translations_model language_code = self.cleaned_data.get('language_code', get_language()) if not new: trans = get_cached_translation(self.instance) if not trans or trans.language_code != language_code: try: trans = get_translation(self.instance, language_code) except trans_model.DoesNotExist: trans = trans_model() else: trans = trans_model() trans = construct_instance(self, trans, self._meta.fields) trans.language_code = language_code trans.master = self.instance self.instance = combine(trans, self.Meta.model) super(TranslatableModelForm, self).save(commit=commit) return self.instance
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList, label_suffix=':', empty_permitted=False, instance=None): """ """ opts = self._meta model_opts = opts.model._meta object_data = {} language = getattr(self, 'language', get_language()) if instance is not None: trans = get_cached_translation(instance) if not trans or trans.language_code != language: try: trans = get_translation(instance, language) except model_opts.translations_model.DoesNotExist: trans = None if trans: object_data = model_to_dict(trans, opts.fields, opts.exclude) # Dirty hack that swaps the id from the translation id, to the master id # This is necessary, because we in this case get the untranslated instance, # and thereafter get the correct translation on save. if "id" in object_data: object_data["id"] = trans.master.id if initial is not None: object_data.update(initial) initial = object_data super(TranslatableModelForm, self).__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted, instance)
def save(self, commit=True): if self.instance.pk is None: fail_message = 'created' new = True else: fail_message = 'changed' new = False super(TranslatableModelForm, self).save(True) trans_model = self.instance._meta.translations_model language_code = self.cleaned_data.get('language_code', get_language()) if not new: trans = get_cached_translation(self.instance) if not trans or trans.language_code != language_code: try: trans = get_translation(self.instance, language_code) except trans_model.DoesNotExist: trans = trans_model() else: trans = trans_model() trans.language_code = language_code trans.master = self.instance trans = save_instance(self, trans, self._meta.fields, fail_message, commit, construct=True) return combine(trans, self.Meta.model)
def __init__( self, data=None, files=None, auto_id="id_%s", prefix=None, initial=None, error_class=ErrorList, label_suffix=":", empty_permitted=False, instance=None, ): opts = self._meta model_opts = opts.model._meta object_data = {} language = getattr(self, "language", get_language()) if instance is not None: trans = get_cached_translation(instance) if not trans: try: trans = get_translation(instance, language) except model_opts.translations_model.DoesNotExist: trans = None if trans: object_data = model_to_dict(trans, opts.fields, opts.exclude) if initial is not None: object_data.update(initial) initial = object_data super(TranslatableModelForm, self).__init__( data, files, auto_id, prefix, object_data, error_class, label_suffix, empty_permitted, instance )
def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList, label_suffix=':', empty_permitted=False, instance=None): opts = self._meta model_opts = opts.model._meta object_data = {} language = getattr(self, 'language', get_language()) if instance is not None: trans = get_cached_translation(instance) if not trans: try: trans = get_translation(instance, language) except model_opts.translations_model.DoesNotExist: trans = None if trans: object_data = model_to_dict(trans, opts.fields, opts.exclude) if initial is not None: object_data.update(initial) initial = object_data super(TranslatableModelForm, self).__init__(data, files, auto_id, prefix, object_data, error_class, label_suffix, empty_permitted, instance)
def save(self, commit=True): if self.instance.pk is None: fail_message = 'created' new = True else: fail_message = 'changed' new = False if self.errors: opts = instance._meta raise ValueError("The %s could not be %s because the data didn't" " validate." % (opts.object_name, fail_message)) trans_model = self.instance._meta.translations_model language_code = self.cleaned_data.get('language_code', get_language()) if not new: trans = get_cached_translation(self.instance) if not trans or trans.language_code != language_code: try: trans = get_translation(self.instance, language_code) except trans_model.DoesNotExist: trans = trans_model() else: trans = trans_model() trans = construct_instance(self, trans, self._meta.fields) trans.language_code = language_code trans.master = self.instance self.instance = combine(trans, self.Meta.model) super(TranslatableModelForm, self).save(commit=commit) return self.instance
def translation(self, instance): translation = get_cached_translation(instance) if translation is None: try: translation = get_translation(instance) except self.opts.translations_model.DoesNotExist: language_code = instance.default_language translation = instance.translations.get(language_code = language_code) set_cached_translation(instance, translation) return translation
def exists_destination_lang_value(item, field, lang): try: dest_trans = get_translation(item, lang) dest_object_field_value = getattr(dest_trans, field) if dest_object_field_value and dest_object_field_value.strip( ) != '': return True except (AttributeError, ObjectDoesNotExist): pass return False
def _post_clean(self): if self.instance.pk: try: trans = trans = get_translation(self.instance, self.instance.language_code) trans.master = self.instance self.instance = combine(trans, self.Meta.model) except self.instance._meta.translations_model.DoesNotExist: language_code = self.cleaned_data.get('language_code', get_language()) self.instance = self.instance.translate(language_code) return super(TranslatableModelForm, self)._post_clean()
def translation(self, instance): translation = get_cached_translation(instance) if translation is None: try: translation = get_translation(instance) except self.opts.translations_model.DoesNotExist: raise self._NoTranslationError('Accessing a translated field requires that ' 'the instance has a translation loaded, or a ' 'valid translation in current language (%s) ' 'loadable from the database' % get_language()) set_cached_translation(instance, translation) return translation
def get_slug_in_language(record, language): if not record: return None if hasattr(record, record._meta.translations_cache) and language == record.language_code: # possibly no need to hit db, try cache return record.lazy_translation_getter('slug') else: # hit db try: translation = get_translation(record, language_code=language) except ObjectDoesNotExist: return None else: return translation.slug
def get_slug_in_language(record, language): if not record: return None if language == record.language_code: return record.lazy_translation_getter('slug') else: # hit db try: translation = get_translation(record, language_code=language) except models.ObjectDoesNotExist: return None else: return translation.slug
def get_absolute_url(self, language=None): language = language or get_current_language() category = self.category try: translation = get_translation(self, language_code=language) except models.ObjectDoesNotExist: translation = None cat_slug = get_slug_in_language(category, language) if translation and cat_slug: with force_language(language): return reverse('aldryn_faq:faq-answer', args=(cat_slug, self.pk)) else: return category.get_absolute_url(language)
def get_translation_from_instance(instance, lang): """ Get the translation from the instance in a specific language, hits the db :param instance: :param lang: :return: """ try: translation = get_translation(instance, lang) except (AttributeError, ObjectDoesNotExist): translation = None return translation
def _post_clean(self): if self.instance.pk: try: # Don't use self.instance.language_code here! That will fail if # the instance is not translated into the current language. If # it succeeded, then the instance would already be translated, # and there'd be no point combining it with the same # translation again. trans = get_translation(self.instance, self.language) trans.master = self.instance self.instance = combine(trans, self.Meta.model) except self.instance._meta.translations_model.DoesNotExist: self.instance = self.instance.translate(self.language) return super(TranslatableModelForm, self)._post_clean()
def load_translation(self, instance): if not hvad_settings.AUTOLOAD_TRANSLATIONS: raise AttributeError('Field %r is a translatable field, but no translation is loaded ' 'and auto-loading is disabled because ' 'settings.HVAD[\'AUTOLOAD_TRANSLATIONS\'] is False' % self.name) try: translation = get_translation(instance) except instance._meta.translations_model.DoesNotExist: raise self._NoTranslationError('Accessing a translated field requires that ' 'the instance has a translation loaded, or a ' 'valid translation in current language (%s) ' 'loadable from the database' % get_language()) set_cached_translation(instance, translation) return translation
def get_slug_in_language(record, language): if not record: return None # possibly no need to hit db, try cache if hasattr(record, record._meta.translations_cache ) and language == record.language_code: return record.lazy_translation_getter('slug') else: # hit db try: translation = get_translation(record, language_code=language) except ObjectDoesNotExist: return None else: return translation.slug
def get_slug_in_language(record, language): if not record: return None # possibly no need to hit db, try cache if HVAD_VERSION >= (2, 0, 0): if get_cached_translation(record) and language == record.language_code: return getattr(record.translations.active, 'slug', None) else: if hasattr(record, record._meta.translations_cache ) and language == record.language_code: return record.lazy_translation_getter('slug') try: translation = get_translation(record, language_code=language) except ObjectDoesNotExist: return None else: return translation.slug
def load_translation(self, instance): """ Load a translation for instance, if the those conditions are met: * AUTOLOAD_TRANSLATIONS is True (otherwise AttributeError is raised) * A translation exists for current language (otherwise NoTranslationError is raised). Returns the loaded translation """ if not hvad_settings.AUTOLOAD_TRANSLATIONS: raise AttributeError( 'Field %r is a translatable field, but no translation is loaded ' 'and auto-loading is disabled because ' 'settings.HVAD[\'AUTOLOAD_TRANSLATIONS\'] is False' % self.name) try: translation = get_translation(instance) except instance._meta.translations_model.DoesNotExist: raise self._NoTranslationError( 'Accessing a translated field requires that ' 'the instance has a translation loaded, or a ' 'valid translation in current language (%s) ' 'loadable from the database' % get_language()) self.query_field.set_cached_value(instance, translation) return translation
def fields_need_translation(self, elem, destination_lang): """ Detect if the tuple needs translation and which fields has to be translated :param elem :param destination_lang: :return: """ fields = self._get_translated_field_names(elem) elem_langs = elem.get_available_languages() # if we don't have a translation for the destination lang we have to include the tuple if destination_lang not in elem_langs: return fields # we have the translation, we decide which fields we need to translate. we have to get the translation first translation = get_translation(elem, destination_lang) result = [] for field in fields: value = getattr(translation, field, '') if not value or value.strip() == '': result.append(field) return result
def handle(self, *args, **options): if not options['app_label']: raise CommandError("Option `--app=...` must be specified.") if not options['destination_lang']: raise CommandError("Option `--lang=...` must be specified. E.g.: (en, de, fr, it, pt, fi)") app_label = options['app_label'] destination_lang = options['destination_lang'] main_lang = self._get_main_language() try: wb = xlrd.open_workbook('{}_{}.xlsx'.format(app_label, destination_lang)) except Exception as e: self.stdout.write('Error: {}'.format(str(e))) sys.exit() sheets = wb.sheets() header_row = 5 init_data_row = 7 init_data_col = 1 # result container result = {} #################### # parse excel data # #################### # we parse every sheet on the workbook for sh in sheets: # if no content then skip this sheet if sh.nrows == (header_row + 1) or sh.name.lower() == 'totales': continue # get the class name class_name = sh.cell_value(2, 1).lower() result[class_name] = [] self.stdout.write('=' * 100) self.stdout.write('sheet: {} - {} - rows {} - cols {}'.format(sh.name, class_name, sh.nrows, sh.ncols)) # proces every row and save it as a dict for row in range(init_data_row, sh.nrows - 2, 3): row_data = {'id': int(sh.cell_value(row, init_data_col))} col = init_data_col + 2 while col <= sh.ncols-4: row_data[sh.cell_value(header_row, col)] = sh.cell_value(row + 1, col) col += 2 result[class_name].append(row_data) # self.stdout.write('result: {}'.format(result)) ############### # create data # ############### for class_name, data in result.items(): model = ContentType.objects.filter(app_label=app_label, model=class_name).get() cls = model.model_class() for row in data: try: item = cls.objects.language(main_lang).get(pk=row['id']) except cls.DoesNotExist: continue try: trans = get_translation(item, destination_lang) except Exception: trans = item.translate(destination_lang) for field, value in row.items(): if field == 'id': continue setattr(trans, field, value) trans.save() ############################ # update translation tasks # ############################ for field, value in row.items(): if field == 'id' or value == '': continue try: task = TransTask.objects.filter( object_class__lower=class_name, object_pk=row['id'], language=TransLanguage.objects.filter(code=destination_lang).get(), object_field=field ).get() task.object_field_value_translation = value task.date_modification = datetime.datetime.now() task.done = True task.save(update_fields=['done', 'date_modification', 'object_field_value_translation']) except TransTask.DoesNotExist: pass # end self.stdout.write('=' * 100) self.stdout.write('end')
def handle(self, *args, **options): if not options['app_label']: raise CommandError("Option `--app=...` must be specified.") if not options['destination_lang']: raise CommandError( "Option `--lang=...` must be specified. E.g.: (en, de, fr, it, pt, fi)" ) app_label = options['app_label'] destination_lang = options['destination_lang'] main_lang = self._get_main_language() try: wb = xlrd.open_workbook('{}_{}.xlsx'.format( app_label, destination_lang)) except Exception as e: self.stdout.write('Error: {}'.format(str(e))) sys.exit() sheets = wb.sheets() header_row = 5 init_data_row = 7 init_data_col = 1 # result container result = {} #################### # parse excel data # #################### # we parse every sheet on the workbook for sh in sheets: # if no content then skip this sheet if sh.nrows == (header_row + 1) or sh.name.lower() == 'totales': continue # get the class name class_name = sh.cell_value(2, 1).lower() result[class_name] = [] self.stdout.write('=' * 100) self.stdout.write('sheet: {} - {} - rows {} - cols {}'.format( sh.name, class_name, sh.nrows, sh.ncols)) # proces every row and save it as a dict for row in range(init_data_row, sh.nrows - 2, 3): row_data = {'id': int(sh.cell_value(row, init_data_col))} col = init_data_col + 2 while col <= sh.ncols - 4: row_data[sh.cell_value(header_row, col)] = sh.cell_value(row + 1, col) col += 2 result[class_name].append(row_data) # self.stdout.write('result: {}'.format(result)) ############### # create data # ############### for class_name, data in result.items(): model = ContentType.objects.filter(app_label=app_label, model=class_name).get() cls = model.model_class() for row in data: try: item = cls.objects.language(main_lang).get(pk=row['id']) except cls.DoesNotExist: continue try: trans = get_translation(item, destination_lang) except Exception: trans = item.translate(destination_lang) for field, value in row.items(): if field == 'id': continue setattr(trans, field, value) trans.save() ############################ # update translation tasks # ############################ for field, value in row.items(): if field == 'id' or value == '': continue try: task = TransTask.objects.filter( object_class__lower=class_name, object_pk=row['id'], language=TransLanguage.objects.filter( code=destination_lang).get(), object_field=field).get() task.object_field_value_translation = value task.date_modification = datetime.datetime.now() task.done = True task.save(update_fields=[ 'done', 'date_modification', 'object_field_value_translation' ]) except TransTask.DoesNotExist: pass # end self.stdout.write('=' * 100) self.stdout.write('end')
def translation(self, instance): cached = getattr(instance, self.opts.translations_cache, None) if not cached: cached = get_translation(instance) setattr(instance, self.opts.translations_cache, cached) return cached