You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

180 lines
6.5 KiB

# -*- coding: utf-8 -*-
from django.conf import settings
#default language
#
ZERO_LANGUAGE = 'ru'
def fill_trans_fields(obj=None, data={}, lang=''):
"""
fills obj translated fields with data in data dictionary with one language
uses 2 types of objects, example: 1) object new - obj = Country.objects.get(id=1)
2) object exist - obj =Country._meta.translations_model.objects.get(language_code = 'ru',master__id=1)
list of fields in first object writes with _translated_field_names and return list of strings
in second object writes with _meta.fields and return list of object. field name we must call obj[0].name
"""
#fills new object
if '_translated_field_names' in dir(obj):
list = obj._translated_field_names
for field in list:
n = data.get('%s_%s'%(field, lang))
if n != None:
setattr(obj, str(field), n)
#fill existing object
else:
list = obj._meta.fields
for field in list:
n = data.get('%s_%s'%(field.name,lang))
if n != None:
setattr(obj,str(field.name), n)
def fill_trans_fields_all(Model, new_obj, data={}, id=None, zero_fields={}):
"""
Fills obj passing trough all languages
id - used for checking existing object
if id=None object doesn't exist and fills new_obj
else fills existing Model object
zero_fields used for generating dictionary which will be checking already populated fields
"""
for lid, (code, name) in enumerate(settings.LANGUAGES):
#fills new object
if not id:
new_obj.translate(code)
fill_trans_fields(new_obj, data,code)
new_obj.save()
#fills existing object
# and fills zero_fields dictionary with data of zero language
else:
existing_obj = Model._meta.translations_model.objects.get(language_code = code,master__id=id) #access to translated fields
if lid==0:
list = existing_obj._meta.fields
for field in list:
zero_fields[field.name] = getattr(existing_obj, field.name)###################
fill_trans_fields(existing_obj, data, code)
existing_obj.save()
def populate(obj=None, data={}, lang=ZERO_LANGUAGE, zero_fields={}):
"""
compare translated fields with empty values and values which was already populate(zero_language)
and populate obj fields if it is true zero_fields fields
block try for fields like id, Foreignkey...
"""
list = obj._meta.fields
for field in list:
#compare empty values
if getattr(obj,field.name) == '':
try: setattr(obj, field.name, data['%s_%s'%(field.name, ZERO_LANGUAGE)])
except: pass
##compare populated values
if field.name in zero_fields:
if getattr(obj,field.name) == zero_fields['%s'%field.name]:
try: setattr(obj, field.name, data['%s_%s'%(field.name, ZERO_LANGUAGE)])
except: pass
def populate_all(Model, data={}, id=None, zero_fields={}):
for lid, (code, name) in enumerate(settings.LANGUAGES):
if lid == 0:
pass
else:
obj = Model._meta.translations_model.objects.get(language_code = code,master__id=id)
populate(obj,data,code,zero_fields)
obj.save()
def fill_with_signal(model, obj, data):
"""
function useful when post_save signal what filling languages exist for this model
"""
all_langs = [code for code, lang in settings.LANGUAGES]
# fields in translations model that doesn't need
bad_fields = ['id', 'language_code', 'master_id']
# translated fields
fields = [field.name for field in model.translations.related.editable_fields() if field.name not in bad_fields]
# translate to first language(require)
# ! first save method call signal that fill require language to all translated fields
if not obj.id:
# new object
obj.translate(all_langs[0])
# go through all fields and set value
for field in fields:
value = data.get('%s_%s'%(field, all_langs[0]), '')
if value:
setattr(obj, field, value.strip())
obj.save()
else:
trans_obj = model._meta.translations_model.objects.get(language_code = all_langs[0],
master__id=getattr(obj, 'id'))
for field in fields:
value = data.get('%s_%s'%(field, all_langs[0]), '')
if value:
setattr(trans_obj, field, value.strip())
trans_obj.save()
# require translation. uses for substitution unfilled form fields
require_transl = model._meta.translations_model.objects.get(language_code = all_langs[0],master__id=getattr(obj, 'id'))
for code in all_langs[1:]:
# fill translation objects
# start from second language
trans_obj = model._meta.translations_model.objects.get(language_code = code,master__id=getattr(obj, 'id'))
for field in fields:
val = data.get('%s_%s'%(field, code), '').strip()
if val == '':
# get value from require translation
setattr(trans_obj, field, getattr(require_transl, field))
else:
setattr(trans_obj, field, val)
trans_obj.save()
def get_translated_fields(obj, exclude_fields=[]):
"""
get translated fields
"""
# get hvad translation objects
translation = obj.translations.all()
# fields which present in database but don't need
bad_fields = ['id', 'master', 'language_code']
# get translated fields without bad fields and exclude fields
translated_fields = [i.name for i in translation[0]._meta.fields if i.name not in bad_fields and i.name not in exclude_fields]
return translated_fields
def get_all_fields(obj, exclude_fields=[]):
"""
Return all simple fields with translated hvad fields
can exclude some fields
"""
# simple fields from django object
fields = [i for i in obj._meta.get_all_field_names() if i not in exclude_fields]
fields += get_translated_fields(obj)
return fields
def get_all_verbose_names(obj, fields):
names = {}
for field in fields:
try:
names[field] = obj._meta.get_field_by_name(field)[0].verbose_name
except:
translations = obj.translations.all()
tr = translations[0]
names[field] = tr._meta.get_field_by_name(field)[0].verbose_name
return names