From 6b178ed049170e285d187ed9cd3e3838d5fbe6a7 Mon Sep 17 00:00:00 2001 From: Nazar Kotyuk Date: Thu, 9 Jan 2014 09:18:06 +0200 Subject: [PATCH] daily commit --- city/models.py | 56 ++++++++--------- functions/signal_additional_func.py | 62 +++++++++++++++++++ functions/translate.py | 11 +++- import_xls/custom_forms.py | 27 +++++--- import_xls/excel_settings.py | 51 +++++++++++---- import_xls/views.py | 53 +--------------- settings/forms.py | 29 ++++++++- settings/models.py | 21 +++++++ .../admin/import templates/export_event.html | 7 +++ .../admin/import templates/import_event.html | 8 ++- templates/admin/settings/settings.html | 9 ++- theme/models.py | 2 +- 12 files changed, 221 insertions(+), 115 deletions(-) create mode 100644 functions/signal_additional_func.py diff --git a/city/models.py b/city/models.py index fcf0be06..3b8a728f 100644 --- a/city/models.py +++ b/city/models.py @@ -1,12 +1,17 @@ # -*- coding: utf-8 -*- -from django.db import models, connection +from django.db import models +from django.db.models.signals import post_save, pre_save +from django.dispatch import receiver from hvad.models import TranslatableModel, TranslatedFields from bitfield import BitField # my models from directories.models import Iata from service.models import Service -# +from settings.models import Setting +# custom dunctions from functions.db import db_table_exists +from functions.form_check import translit_with_separator +from functions.signal_additional_func import fill_missing_languages, fill_meta_information #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 [] @@ -48,12 +53,11 @@ class City(TranslatableModel): def __unicode__(self): 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 + def save(self, *args, **kwargs): + + super(City, self).save(*args, **kwargs) + -from functions.translate import get_translated_fields @receiver(post_save) def city_post_save_handler(sender, **kwargs): @@ -66,31 +70,25 @@ def city_post_save_handler(sender, **kwargs): 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() + fill_missing_languages(obj) + #fill_meta_information(obj) if isinstance(obj, CityTranslation): - # object is Translation - print('trans') + # object is Translation - set url if obj.language_code == 'ru': city = City.objects.get(id=obj.master_id) country = city.country city.url = '%s-%s'%(translit_with_separator(country.name), translit_with_separator(obj.name)) - city.save() \ No newline at end of file + city.save() + +""" +@receiver(pre_save) +def sett(sender, **kwargs): + obj = kwargs['instance'] + if isinstance(obj, CityTranslation): + if obj.title == '111': + obj.title == '222' + obj.save() +""" + + diff --git a/functions/signal_additional_func.py b/functions/signal_additional_func.py new file mode 100644 index 00000000..656805d1 --- /dev/null +++ b/functions/signal_additional_func.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +from settings.models import settings_dict, Setting + + +from django.conf import settings +from functions.translate import get_translated_fields + +def fill_missing_languages(obj): + all_langs = [code for code, lang in settings.LANGUAGES] + obj_langs = obj.get_available_languages() + missing_languages = list(set(all_langs) - set(obj_langs)) + if missing_languages: + # get first Translation object (require) + 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() + +#from city.models import City +#city = City.objects.get(id=37) +#city +# +def fill_meta_information(obj): + s_list = settings_dict.get(obj.__class__.__name__) + if s_list: + for code, lang in settings.LANGUAGES: + fields_with_setting = [(setting.get('field_name'), Setting.objects.get(key=setting['key']).get_value(code)) \ + for setting in s_list if setting.get('type') =='transl'] + tr = obj._meta.translations_model.objects.get(language_code=code, master__id=getattr(obj, 'id')) + + + for field in fields_with_setting: + setattr(tr, field[0], field[1]) + tr.save() + + + #return fields_with_setting + + """ + s_list = settings_dict.get(obj.__class__.__name__) + return s_list + for s in s_list: + setting = Setting.objects.get(key=s.get('key')) + if setting.type != 'transl': + setattr(obj, s.get('field_name'), setting.get_value()) + else: + for code, lang in settings.LANGUAGES: + tr = obj._meta.translations_model.objects.get(language_code=code, master__id=getattr(obj, 'id')) + setattr(tr, s.get('field_name'), setting.get_value(code)) + tr.save() + """ + + + + diff --git a/functions/translate.py b/functions/translate.py index 6a1a9285..96ac6fd2 100644 --- a/functions/translate.py +++ b/functions/translate.py @@ -99,16 +99,21 @@ def fill_with_signal(model, obj, data): 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 - # translate into first language obj.translate(all_langs[0]) # go through all fields and set value for field in fields: setattr(obj, field, data.get('%s_%s'%(field, all_langs[0]))) - - # first save method call signal that fill require language to all translated fields 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: + setattr(trans_obj, field, data.get('%s_%s'%(field, all_langs[0]))) + 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')) diff --git a/import_xls/custom_forms.py b/import_xls/custom_forms.py index c2c61643..260b4860 100644 --- a/import_xls/custom_forms.py +++ b/import_xls/custom_forms.py @@ -63,11 +63,18 @@ class ImportEventForm(forms.Form): # in function we add language(need for relation fields) # and extra value from object (like for city need country) - value = func(cell, lang, getattr(object, extra_value)) + # условие заглушка для мени ту мени + if object.id == None and (field_name=='theme' or field_name=='tag'): + pass + else: + value = func(cell, lang, getattr(object, extra_value)) else: value = func(cell) - - setattr(object, field_name, value) + # условие заглушка для мени ту мени + if object.id == None and (field_name=='theme' or field_name=='tag'): + pass + else: + setattr(object, field_name, value) object.save() @@ -96,12 +103,7 @@ class ExportEventForm(forms.Form): if not objects: # not found any objects return None - message = 'По даному запросу объектов не найдено' - args = {} - args.update(csrf(request)) - args['message'] = message - args['form'] = form - return render_to_response('export_event.html', args) + workbook = xlwt.Workbook(encoding = 'utf8') # new tab @@ -135,9 +137,14 @@ class ExportEventForm(forms.Form): else: worksheet.write(row+2, col, field.get('type')(value)) col += 1 - return workbook + def get_fname(self): + data = self.cleaned_data + f_name = data['language']+'_'+data['event'].split('.')[1]\ + +' from: %s'%data['date_from']+' to: %s'%data['date_to']+'.xls' + return f_name + def clean_theme(self): """ diff --git a/import_xls/excel_settings.py b/import_xls/excel_settings.py index 55dc7ac9..faf3f915 100644 --- a/import_xls/excel_settings.py +++ b/import_xls/excel_settings.py @@ -2,6 +2,7 @@ from country.models import Country from city.models import City from theme.models import Theme, Tag +from hvad.utils import get_translation_aware_manager def get_bool(value): if value: @@ -38,7 +39,7 @@ def get_tag(tag, theme): # list of tags with current theme tag_list = [str(tag) for tag in tags if tag.theme == theme] - result += '['+','.join(tag_list)+']' + result += '['+', '.join(tag_list)+']' return result @@ -47,17 +48,17 @@ def get_tag(tag, theme): field_settings = [ {'name': 'id', 'verbose_name': 'id', 'type': get_int, 'width':1500}, {'name': 'url', 'verbose_name': 'url', 'type': str}, - {'name': 'name', 'verbose_name': 'Имя', 'type': str, 'width':8000,}, + {'name': 'name', 'verbose_name': 'Имя', 'type': str, 'width':8000}, {'name': 'data_begin', 'verbose_name': 'Дата начала', 'type': str}, {'name': 'data_end', 'verbose_name': 'Дата окончания', 'type': str}, + {'name': 'audience', 'verbose_name': 'Аудитория', 'type': get_audience}, {'name': 'main_title', 'verbose_name': 'Краткое описание', 'type': str}, {'name': 'description', 'verbose_name': 'Описание', 'type': str}, - {'name': 'audience', 'verbose_name': 'Аудитория', 'type': get_audience}, {'name': 'country', 'verbose_name': 'Страна', 'type': str}, {'name': 'city', 'verbose_name': 'Город', 'type': str}, - {'name': 'theme', 'verbose_name': 'Тематика', 'type': get_theme}, - {'name': 'tag', 'verbose_name': 'Теги', 'type': get_tag}, - {'name': 'periodic', 'verbose_name': 'Периодичность', 'type': str}, + {'name': 'theme', 'verbose_name': 'Тематика', 'type': get_theme, 'width':8000}, + {'name': 'tag', 'verbose_name': 'Теги', 'type': get_tag, 'width':8000}, + #{'name': 'periodic', 'verbose_name': 'Периодичность', 'type': str}, {'name': 'web_page', 'verbose_name': 'Веб страница', 'type': str}, {'name': 'time', 'verbose_name': 'Время проведения', 'type': str}, {'name': 'products', 'verbose_name': 'Экспонируемые продукты', 'type': str}, @@ -75,8 +76,8 @@ field_settings = [ {'name': 'max_open_area', 'verbose_name': 'Максимальная цена открытой площади', 'type': get_int}, {'name': 'min_area', 'verbose_name': 'Минимальная площадь', 'type': get_int}, {'name': 'max_area', 'verbose_name': 'Максимальная площадь', 'type': get_int}, - {'name': 'is_published', 'verbose_name': 'Опубликована', 'type': get_bool, 'width':1000}, - {'name': 'canceled_by_administrator', 'verbose_name': 'Отменена администратором', 'type': get_bool, 'width':1000} + {'name': 'is_published', 'verbose_name': 'Опубликована', 'type': get_bool}, + {'name': 'canceled_by_administrator', 'verbose_name': 'Отменена администратором', 'type': get_bool} ] @@ -93,7 +94,7 @@ def to_int(val): return None -from hvad.utils import get_translation_aware_manager + def to_country(value): try: query = get_translation_aware_manager(Country) @@ -140,8 +141,10 @@ def to_theme(value, lang='ru'): theme_names = value.split(', ') theme_objects = [] for name in theme_names: + try: - theme = Theme.objects.get(name=name) + objects = get_translation_aware_manager(Theme) + theme = objects.filter(name=name)[0] except: theme = Theme() theme.translate(lang) @@ -152,9 +155,30 @@ def to_theme(value, lang='ru'): return theme_objects -#def to_tag(value): - - +def to_tag(value, lang, themes): + value = value.replace('[', '') + themes = themes.all() + # list tags by themes + value = value.split(']') + + arr = [] + bla = value[0].split(', ') + for theme_number, theme in enumerate(themes): + for val in value[theme_number].split(', '): + if val: + try: + objects = get_translation_aware_manager(Tag) + tag = objects.language(lang).filter(name=val, theme=theme) + tag = tag[0] + except: + tag = Tag() + tag.theme = theme + tag.translate(lang) + tag.name = val + tag.save() + + arr.append(tag) + return arr @@ -169,6 +193,7 @@ import_settings={ 'country': {'func': to_country}, 'city': {'func': to_city, 'extra_values': 'country'}, 'theme': {'func': to_theme}, + 'tag': {'func': to_tag, 'extra_values': 'theme'}, 'periodic': {'func': str}, 'web_page': {'func': str}, 'time': {'func': str}, diff --git a/import_xls/views.py b/import_xls/views.py index 618ed9d5..140e27ab 100644 --- a/import_xls/views.py +++ b/import_xls/views.py @@ -48,57 +48,8 @@ def export_event(request): if workbook is None: pass else: - return xls_to_response(workbook, 'My Worksheet.xls') - """ - data = form.cleaned_data - # get model - model = get_model(data['event'].split('.')[0], data['event'].split('.')[1]) - # get objects - objects = model.objects.language(data['language']).filter(data_begin__range=[data['date_from'], data['date_to']], - country__in=data['country'], - theme__in=data['theme'] - ).distinct() - - if not objects: - # not found any objects - message = 'По даному запросу объектов не найдено' - args = {} - args.update(csrf(request)) - args['message'] = message - args['form'] = form - return render_to_response('export_event.html', args) - - workbook = xlwt.Workbook(encoding = 'utf8') - # new tab - worksheet = workbook.add_sheet('My Worksheet') - - # Create the Font for first rows - font = xlwt.Font() - font.name = 'Times New Roman' - font.bold = True - style = xlwt.XFStyle() - # Create the Style - style.font = font - - for row, object in enumerate(objects): - # column number - col = 0 - for field in field_settings: - try: - value = getattr(object, field['name']) - except AttributeError: - # doesnt have such field. exit from iteration - continue - - if row == 0: - # first iteration. set names. set columns width - worksheet.write(0, col, field.get('verbose_name', 'default'), style) - worksheet.write(1, col, field.get('name'), style) - worksheet.col(col).width = field.get('width', 3333) - - worksheet.write(row+2, col, field.get('type')(value)) - col += 1 - """ + f_name = form.get_fname() + return xls_to_response(workbook, f_name) #return xls_to_response(workbook, 'My Worksheet.xls') else: diff --git a/settings/forms.py b/settings/forms.py index a57099c8..2014c5fe 100644 --- a/settings/forms.py +++ b/settings/forms.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django import forms -from models import Setting +from models import Setting, settings_dict from django.conf import settings from functions.translate import fill_trans_fields, populate, ZERO_LANGUAGE, populate_all, fill_trans_fields_all @@ -18,6 +18,25 @@ class SettingsForm(forms.Form): super(SettingsForm, self).__init__(*args, **kwargs) # creates translated form fields, example: name_ru, name_en # len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs + for model_name in settings_dict.values(): + for setting in model_name: + item = Setting.objects.get(key=setting['key']) + if setting['type'] != 'transl': + self.fields[setting['key']] = forms.CharField(label=setting['verbose_name'], initial=item.get_value(), + required=False) + else: + if len(settings.LANGUAGES) in range(10): + for lid, (code, name) in enumerate(settings.LANGUAGES): + # using enumerate for detect iteration number + # first iteration is a default lang so it required fields + required = True if lid == 0 else False + self.fields['%s_%s' %(setting['key'], code)] = forms.CharField(label=setting['verbose_name'], + initial=item.get_value(code), + required=required, + widget=forms.TextInput( + attrs={'style':'width: 450px'})) + + """ settings_list = Setting.objects.all() for item in settings_list: if item.type != 'transl': @@ -29,8 +48,12 @@ class SettingsForm(forms.Form): # using enumerate for detect iteration number # first iteration is a default lang so it required fields required = True if lid == 0 else False - self.fields['%s_%s' %(item.key, code)] = forms.CharField(label=getattr(item, 'key'), initial=item.get_value(code), - required=required,widget=forms.TextInput(attrs={'style':'width: 450px'})) + self.fields['%s_%s' %(item.key, code)] = forms.CharField(label=getattr(item, 'key'), + initial=item.get_value(code), + required=required, + widget=forms.TextInput( + attrs={'style':'width: 450px'})) + """ def save(self): diff --git a/settings/models.py b/settings/models.py index d688b521..bbeb7c99 100644 --- a/settings/models.py +++ b/settings/models.py @@ -14,6 +14,8 @@ class Setting(TranslatableModel): Create Settings model, which stores different settings of project Uses hvad.TranslatableModel which is child of django.db.models class + + Setting create only by admin """ VALUES = ('int', 'text', 'transl', 'date') @@ -54,6 +56,25 @@ class Setting(TranslatableModel): else: setattr(self, self.type, value) +# dictionaty of models settings +# every model have list of settings +# key: setting in db, field_name: field in model +settings_dict = dict(City=[{'key': 'city_title', 'field_name': 'title', 'type': 'transl', 'verbose_name': 'title Городов'}, + {'key': 'city_keywords', 'field_name': 'keywords', 'type': 'transl', 'verbose_name': 'keywords'}, + {'key': 'city_descriptions', 'field_name': 'descriptions', 'type': 'transl', 'verbose_name': 'description'}], + #Country=[{'key': 'country_title', 'type': 'transl', 'verbose_name': 'title'}, + # {'key': 'country_keywords', 'type': 'transl', 'verbose_name': 'keywords'}, + # {'key': 'country_descriptions', 'type': 'transl', 'verbose_name': 'description'}] +) + +#from settings.models import settings, Setting +#country_set = settings.get('country') +#for s in country_set: +# set = Setting(key=s['key'], type=s['type']) +# set.save() + + + from django.db.models.signals import post_save from django.dispatch import receiver diff --git a/templates/admin/import templates/export_event.html b/templates/admin/import templates/export_event.html index 0e121a10..24da469c 100644 --- a/templates/admin/import templates/export_event.html +++ b/templates/admin/import templates/export_event.html @@ -76,6 +76,13 @@ +
+

Дата обязательна. Если направление или страна не заплолнено выборка по всем направлениям или странам

+ + + +
+
diff --git a/templates/admin/import templates/import_event.html b/templates/admin/import templates/import_event.html index 1acd078c..c69203dc 100644 --- a/templates/admin/import templates/import_event.html +++ b/templates/admin/import templates/import_event.html @@ -33,11 +33,13 @@
-

Поле id менять для редактирования старого события

+

Обязательные поля: Имя, дата начала, дата окончания, страна, город, тематика, валюта


-

Для создания нового события оставить поле id пустым

+

Поле id не менять для редактирования старого события. Для создания нового события оставить поле id пустым


-

Город должен быть после страны, а тег после тематики

+

Город должен быть после страны, а тег после тематики, для коректного сохранения даных

+ +
diff --git a/templates/admin/settings/settings.html b/templates/admin/settings/settings.html index e7f79fde..6f8c6d45 100644 --- a/templates/admin/settings/settings.html +++ b/templates/admin/settings/settings.html @@ -6,12 +6,17 @@
{% csrf_token %} {# template hall placeconference #} - {% with field='place_conf_hall' form=form languages=languages %} + {% with field='city_title' form=form languages=languages %} {% include 'admin/forms/multilang.html' %} {% endwith %} {# template hall placeexposition #} - {% with field='place_exp_hall' form=form languages=languages %} + {% with field='city_descriptions' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + + {# template hall placeexposition #} + {% with field='city_keywords' form=form languages=languages %} {% include 'admin/forms/multilang.html' %} {% endwith %} diff --git a/theme/models.py b/theme/models.py index 2cd74799..fe263606 100644 --- a/theme/models.py +++ b/theme/models.py @@ -100,7 +100,7 @@ class Tag(TranslatableModel): #set manager of this model objects = TagManager() - theme = models.ForeignKey(Theme, on_delete=models.PROTECT, related_name='themes') + theme = models.ForeignKey(Theme, on_delete=models.PROTECT, related_name='tags') #translated fields translations = TranslatedFields( name = models.CharField(max_length=100),