in src/olympia/amo/utils.py [0:0]
def attach_trans_dict(model, objs):
"""Put all translations from all non-deferred translated fields from objs
into a translations dict on each instance."""
# Get the ids of all the translations we need to fetch.
try:
deferred_fields = objs[0].get_deferred_fields()
except IndexError:
return
fields = [
field
for field in model._meta.translated_fields
if field.attname not in deferred_fields
]
ids = [
getattr(obj, field.attname)
for field in fields
for obj in objs
if getattr(obj, field.attname, None) is not None
]
if ids:
# Get translations in a dict, ids will be the keys. It's important to
# consume the result of sorted_groupby, which is an iterator.
qs = Translation.objects.filter(id__in=ids, localized_string__isnull=False)
else:
qs = []
all_translations = {
field_id: sorted(list(translations), key=lambda t: t.locale)
for field_id, translations in sorted_groupby(qs, lambda t: t.id)
}
def get_locale_and_string(translation, new_class):
"""Convert the translation to new_class (making PurifiedTranslations
and LinkifiedTranslations work) and return locale / string tuple."""
converted_translation = new_class()
converted_translation.__dict__ = translation.__dict__
return (converted_translation.locale.lower(), str(converted_translation))
# Build and attach translations for each field on each object.
for obj in objs:
if not obj:
continue
obj.translations = collections.defaultdict(list)
for field in fields:
t_id = getattr(obj, field.attname, None)
field_translations = all_translations.get(t_id, None)
if not t_id or field_translations is None:
continue
obj.translations[t_id] = [
get_locale_and_string(t, field.remote_field.model)
for t in field_translations
]