From 0efd66e73aaca962e7d1ee9b7c25a9a055d03639 Mon Sep 17 00:00:00 2001 From: Nazar Kotjuk Date: Tue, 24 Dec 2013 09:22:58 +0200 Subject: [PATCH] signal in country and city models that creates all tranlate fields with one value --- city/models.py | 48 ++++++++++- country/forms.py | 44 ++++++++-- country/models.py | 83 ++++++++++++++++++- country/signals.py | 24 ------ functions/translate.py | 22 +++-- import_xls/excel_settings.py | 16 +++- import_xls/views.py | 16 ++-- .../admin/import templates/import_event.html | 14 ++++ 8 files changed, 213 insertions(+), 54 deletions(-) diff --git a/city/models.py b/city/models.py index d40b4056..64db1de1 100644 --- a/city/models.py +++ b/city/models.py @@ -46,4 +46,50 @@ class City(TranslatableModel): modified = models.DateTimeField(auto_now=True) def __unicode__(self): - return self.lazy_translation_getter('name', self.pk) \ No newline at end of file + return self.lazy_translation_getter('name', self.pk) + +from django.db.models.signals import pre_save, post_save +from django.dispatch import receiver +from django.conf import settings +from functions.form_check import translit_with_separator + +from functions.translate import get_translated_fields + +@receiver(post_save) +def city_post_save_handler(sender, **kwargs): + """ + objects saves two times: + - first time Country object + - second time CountryTranslation object + object must have at least one Translation + """ + + obj = kwargs['instance'] + if isinstance(obj, City): + # object is City + # what languages must be + all_langs = [code for code, lang in settings.LANGUAGES] + # what languages are + obj_langs = obj.get_available_languages() + # + missing_languages = list(set(all_langs) - set(obj_langs)) + # get first Translation object + translation = obj.translations.all()[0] + # + fields = get_translated_fields(obj) + for code in missing_languages: + # translate + obj.translate(code) + # go through all fields and set value + for field in fields: + setattr(obj, field, getattr(translation, field)) + + obj.save() + + if isinstance(obj, CityTranslation): + # object is Translation + print('trans') + if obj.language_code == 'ru': + city = City.objects.get(id=obj.master_id) + city.url = translit_with_separator(obj.name) + city.save() \ No newline at end of file diff --git a/country/forms.py b/country/forms.py index 7d42b910..1c075534 100644 --- a/country/forms.py +++ b/country/forms.py @@ -13,6 +13,9 @@ from functions.files import check_tmp_files from functions.form_check import is_positive_integer, translit_with_separator +from functions.translate import get_translated_fields + + tz = [ (99, ''), (-12.0, '(GMT -12:00) Eniwetok, Kwajalein'), (-11.0,'(GMT -11:00) Midway Island, Samoa'), @@ -127,6 +130,39 @@ class CountryForm(forms.Form): country.language.clear() country.currency.clear() + 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 Country.translations.related.editable_fields() if field.name not in bad_fields] + + # translate to first language(require) + if not id: + country.translate(all_langs[0]) + # go through all fields and set value + for field in fields: + setattr(country, field, data.get('%s_%s'%(field, all_langs[0]))) + + # first save method call signal that fill require language to all translated fields + country.save() + else: + # require translation. uses for substitution unfilled form fields + require_transl = Country._meta.translations_model.objects.get(language_code = all_langs[0],master__id=getattr(country, 'id')) + + for code in all_langs[1:]: + # fill translation objects + # start from second language + obj = Country._meta.translations_model.objects.get(language_code = code,master__id=getattr(country, 'id')) + for field in fields: + val = data.get('%s_%s'%(field, code)) + if val == '': + # get value from require translation + setattr(obj, field, getattr(require_transl, field)) + else: + setattr(obj, field, val) + + obj.save() + country.url = translit_with_separator(data['name_ru']).lower() country.population = data['population'] country.teritory = data['teritory'] @@ -154,15 +190,7 @@ class CountryForm(forms.Form): # uses because in the next loop data will be overwritten country.save() - #populate fields with zero language - zero_fields = {} - - fill_trans_fields_all(Country, country, data, id, zero_fields) - #autopopulate - #populate empty fields and fields which was already populated - country_id = getattr(country, 'id') - populate_all(Country, data, country_id, zero_fields) #save files check_tmp_files(country, data['key']) diff --git a/country/models.py b/country/models.py index 2c125ecc..d0711b86 100644 --- a/country/models.py +++ b/country/models.py @@ -11,6 +11,8 @@ from functions.custom_fields import EnumField from bitfield import BitField from functions.db import db_table_exists +from django.conf import settings + #check if table exist and create flags if true flags = [str(item.id) for item in Service.objects.all()] if db_table_exists('service_service') else [] @@ -64,5 +66,84 @@ class Country(TranslatableModel): ) + """ + def __init__(self, **kwargs): + name = kwargs.get('name') + if name: + for code, language in settings.LANGUAGES: + self.translate(code) + self.name = name + else: + pass + """ + def __unicode__(self): - return self.lazy_translation_getter('name', unicode(self.pk)) \ No newline at end of file + return self.lazy_translation_getter('name', unicode(self.pk)) + + +from django.db.models.signals import pre_save, post_save +#from models import Country +from django.dispatch import receiver +from django.conf import settings +from functions.form_check import translit_with_separator + + +from functions.translate import get_translated_fields + +@receiver(post_save) +def country_post_save_handler(sender, **kwargs): + """ + objects saves two times: + - first time Country object + - second time CountryTranslation object + object must have at least one Translation + """ + + obj = kwargs['instance'] + if isinstance(obj, Country): + # object is Country + # what languages must be + all_langs = [code for code, lang in settings.LANGUAGES] + # what languages are + obj_langs = obj.get_available_languages() + # + missing_languages = list(set(all_langs) - set(obj_langs)) + # get first Translation object + translation = obj.translations.all()[0] + # + fields = get_translated_fields(obj) + for code in missing_languages: + # translate + obj.translate(code) + # go through all fields and set value + for field in fields: + setattr(obj, field, getattr(translation, field)) + + obj.save() + + if isinstance(obj, CountryTranslation): + # object is Translation + if obj.language_code == 'ru': + country = Country.objects.get(id=obj.master_id) + country.url = translit_with_separator(obj.name) + country.save() + #if not obj.url: + # obj.url = translit_with_separator(obj.name) + # obj.save() + """ + if kwargs['created']: + print(obj.name) + if not obj.url: + obj.url = translit_with_separator(obj.name) + obj.save() + """ + """ + if not obj.title: + # len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs + if len(settings.LANGUAGES) in range(10): + for code, name in settings.LANGUAGES: + obj.translate(code) + obj.title = '111' + obj.save() + """ + diff --git a/country/signals.py b/country/signals.py index 8a4b5fb0..40a96afc 100644 --- a/country/signals.py +++ b/country/signals.py @@ -1,25 +1 @@ # -*- coding: utf-8 -*- -from django.db.models.signals import pre_save, post_save -from models import Country -from django.dispatch import receiver -from django.conf import settings -from functions.form_check import translit_with_separator - -@receiver(post_save) -def country_post_save_handler(sender, **kwargs): - """ - - """ - obj = kwargs['instance'] - if kwargs['created']: - if not obj.url: - obj.url = translit_with_separator(obj.name) - - if not obj.title: - # len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs - if len(settings.LANGUAGES) in range(10): - for code, name in settings.LANGUAGES: - obj.translate(code) - obj.title = '111' - obj.save() - diff --git a/functions/translate.py b/functions/translate.py index 392cf9b4..7a83e964 100644 --- a/functions/translate.py +++ b/functions/translate.py @@ -91,25 +91,29 @@ def populate_all(Model, data={}, id=None, zero_fields={}): obj.save() -def get_all_fields(obj, exclude_fields=[]): +def get_translated_fields(obj, exclude_fields=[]): """ - Return all simple fields with translated hvad fields - - can exclude some fields + get translated fields """ - - # simple fields from django object - fields = [i for i in obj._meta.get_all_field_names() if i not in exclude_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 + -# fields += translated_fields -# rields2 = [fields for i in field_settings] +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): diff --git a/import_xls/excel_settings.py b/import_xls/excel_settings.py index 11e182b8..ed6f5562 100644 --- a/import_xls/excel_settings.py +++ b/import_xls/excel_settings.py @@ -81,7 +81,7 @@ def to_country(value): from city.models import City -def to_city(value): +def to_city(value, lang=None, country=None): try: # get city by name objects = get_translation_aware_manager(City) @@ -89,7 +89,15 @@ def to_city(value): city = objects.filter(name=value)[0] return city except IndexError: - return None + # not found + # try to create new city + city = City() + city.translate(lang) + city.name = value + city.save() + return city + + AUDIENCE1 = ((None,'Не выбрано'), ('experts', 'Специалисты'), @@ -110,7 +118,7 @@ def to_audience(value): return '' -def get_cell(field_name, value): +def get_cell(field_name, value, lang=None): return {#'id': int(value), 'url': str(value), 'name': str(value), @@ -120,7 +128,7 @@ def get_cell(field_name, value): 'description': str(value), 'audience': to_audience(value), 'country': to_country(value), - 'city': to_city(value), + 'city': to_city(value, lang=lang), #'periodic': str(value), 'web_page': str(value), 'time': str(value), diff --git a/import_xls/views.py b/import_xls/views.py index 32224f62..e4803f49 100644 --- a/import_xls/views.py +++ b/import_xls/views.py @@ -50,6 +50,10 @@ import_settings = [ @login_required def import_event(request): + args = {} + form = ImportEventForm() + args.update(csrf(request)) + args['form'] = form if request.POST: form = ImportEventForm(request.POST, request.FILES) if form.is_valid(): @@ -67,7 +71,7 @@ def import_event(request): if row_number > 1: object = model.objects.language(request.POST['language']).get(id=row[0]) for col_number, cell in enumerate(row): - value = get_cell(field_names[col_number], cell) + value = get_cell(field_names[col_number], cell, request.POST['language']) # if not value: pass @@ -78,14 +82,12 @@ def import_event(request): else: pass + args['message'] = 'Success' + return render_to_response('import_event.html', args) + + - return HttpResponse(request.POST['event']) - else: - form = ImportEventForm() - args = {} - args.update(csrf(request)) - args['form'] = form return render_to_response('import_event.html', args) diff --git a/templates/admin/import templates/import_event.html b/templates/admin/import templates/import_event.html index 58b6fd74..4e08217f 100644 --- a/templates/admin/import templates/import_event.html +++ b/templates/admin/import templates/import_event.html @@ -39,4 +39,18 @@ + + {% if message %} +
+ {{ message }} +
+ {% endif %} + {% endblock %} \ No newline at end of file