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
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
|
|
|