diff --git a/accounts/admin.py b/accounts/admin.py index fd3ac63f..ac23916f 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -198,7 +198,7 @@ def change_password(request): #user.set_password(form.cleaned_data.get('new_password')) #user.save() success['success'] = True - success['message'] = _(u'Пароль именен') + success['message'] = _(u'Пароль изменен') return HttpResponse(json.dumps(success), content_type='application/json') else: errors = {'errors': [_(u'Не правильный пароль')]} diff --git a/accounts/edit_forms.py b/accounts/edit_forms.py index cb687a90..320935a1 100644 --- a/accounts/edit_forms.py +++ b/accounts/edit_forms.py @@ -30,7 +30,7 @@ class NameForm(forms.ModelForm): class HomeForm(forms.ModelForm): - city = forms.CharField(label='Город', required=False, + city = forms.CharField(label=_(u'Город'), required=False, widget=forms.HiddenInput(attrs={'class': 'select2'})) country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()], required=False, widget=forms.Select(attrs={'class': 'select2'})) @@ -150,4 +150,4 @@ class AboutForm(forms.ModelForm): class Meta: model = Profile - fields = ('about',) \ No newline at end of file + fields = ('about',) diff --git a/accounts/forms.py b/accounts/forms.py index d47d65c3..36da7fc9 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -27,8 +27,8 @@ def clean_relation_field(inst, field_name, model): class UserCreationForm(forms.ModelForm): - password1 = forms.CharField(label='Пароль', widget=forms.PasswordInput(render_value=False)) - password2 = forms.CharField(label='Повторите пароль', widget=forms.PasswordInput(render_value=False)) + password1 = forms.CharField(label=_(u'Пароль'), widget=forms.PasswordInput(render_value=False)) + password2 = forms.CharField(label=_(u'Повторите пароль'), widget=forms.PasswordInput(render_value=False)) class Meta: model = User @@ -43,14 +43,14 @@ class UserCreationForm(forms.ModelForm): User.objects.get(email=email) except User.DoesNotExist: return email - raise forms.ValidationError('Пользователь с таким email уже существует') + raise forms.ValidationError(_(u'Пользователь с таким email уже существует')) def clean_password2(self): password1 = self.cleaned_data.get('password1') password2 = self.cleaned_data.get('password2') if password1 and password2 and password1 != password2: - raise forms.ValidationError('Пароли не совпадают') + raise forms.ValidationError(_(u'Пароли не совпадают')) return password2 def save(self, commit=True): @@ -65,10 +65,10 @@ class UserCreationForm(forms.ModelForm): class UserForm(forms.ModelForm): # email = forms.EmailField(widget=forms.TextInput(attrs={'disabled' : True}), required=False) - country = forms.ChoiceField(label='Страна', choices=[(item.id, item.name) for item in Country.objects.language().all()], + country = forms.ChoiceField(label=_(u'Страна'), choices=[(item.id, item.name) for item in Country.objects.language().all()], required=False) - city = forms.CharField(label='Город', widget=forms.HiddenInput(), required=False) - company = forms.ChoiceField(label='Компания', + city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput(), required=False) + company = forms.ChoiceField(label=_(u'Компания'), choices=[(item.id, item.name) for item in Company.objects.language().all()], required=False) @@ -149,7 +149,7 @@ class UserForm(forms.ModelForm): if phone.isdigit(): return phone else: - raise forms.ValidationError('Введите правильный код страны') + raise forms.ValidationError(_(u'Введите правильный код страны')) class ChangePasswordForm(forms.Form): @@ -201,9 +201,9 @@ class EmailAnnouncementForm(forms.Form): class RegistrationCompleteForm(forms.ModelForm): - country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), + country = forms.ModelChoiceField(label=_(u'Страна'), queryset=Country.objects.all(), widget=forms.Select(attrs={'class': 'select2'})) - city = forms.CharField(label='Город', widget=forms.HiddenInput()) + city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput()) url = forms.CharField(widget=forms.TextInput(attrs={'placeholder': _(u'url(обязательно)')})) # code_country = forms.ChoiceField(label=_(u'код страны'), initial='70', diff --git a/accounts/models.py b/accounts/models.py index 413b9560..a49485c7 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -22,7 +22,7 @@ class UserManager(BaseUserManager): def create_user(self, email, first_name, last_name, password=None, **extra_fields): now = timezone.now() if not email: - raise ValueError('Вы должни ввести электронную почту') + raise ValueError(_(u'Вы должни ввести электронную почту')) user = self.model( email=UserManager.normalize_email(email), @@ -38,7 +38,7 @@ class UserManager(BaseUserManager): def create_superuser(self, username, first_name, last_name, password, **extra_fields): if not username: - raise ValueError('Вы должни ввести электронную почту') + raise ValueError(_(u'Вы должни ввести электронную почту')) username = UserManager.normalize_email(username) @@ -82,7 +82,7 @@ class User(AbstractBaseUser, PermissionsMixin, GetURLorPK): #unique = True, db_index=True, ) - username = models.CharField(verbose_name='Email', max_length=255, unique=True, db_index=True) + username = models.CharField(verbose_name=_(u'Email'), max_length=255, unique=True, db_index=True) first_name = models.CharField(verbose_name=_(u'First name'), max_length=255) last_name = models.CharField(verbose_name=_(u'Last name'), max_length=255) rating = models.IntegerField(verbose_name=_(u'Рейтинг'), default=100)# добавить индекс в базе @@ -94,15 +94,15 @@ class User(AbstractBaseUser, PermissionsMixin, GetURLorPK): date_registered = models.DateTimeField(verbose_name=_(u'Дата регистрации'), blank=True, null=True) date_modified = models.DateTimeField(verbose_name=_(u'Изменен'), auto_now=True) #relations - organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True, + organiser = models.ForeignKey('organiser.Organiser', verbose_name=_(u'Организатор'), blank=True, null=True, unique=True, on_delete=models.PROTECT) - translator = models.ForeignKey('translator.Translator', verbose_name='Переводчик', blank=True, null=True, + translator = models.ForeignKey('translator.Translator', verbose_name=_(u'Переводчик'), blank=True, null=True, unique=True, on_delete=models.PROTECT, related_name='user') company = models.ForeignKey('company.Company', verbose_name=_(u'Компания'), blank=True, null=True, related_name='users') - position = models.CharField(verbose_name='Должность', max_length=255, blank=True) + position = models.CharField(verbose_name=_(u'Должность'), max_length=255, blank=True) blocked = models.BooleanField(verbose_name=_(u'Заблокирован?'), default=False) objects = UserManager() diff --git a/article/admin.py b/article/admin.py index 70698ca5..bd780402 100644 --- a/article/admin.py +++ b/article/admin.py @@ -15,6 +15,7 @@ from file.forms import FileModelForm, FileForm #custom views from functions.custom_views import objects_list, add_object_with_file, delete_object from functions.views_help import get_referer +from django.utils.translation import ugettext_lazy as _ class ArticleDeleteView(DeleteView): diff --git a/article/forms.py b/article/forms.py index 9fc5304c..52b4f190 100644 --- a/article/forms.py +++ b/article/forms.py @@ -16,12 +16,12 @@ from conference.models import Conference class _BlogForm(forms.Form): type = Article.blog - theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=ThemeBlog.objects.all(), required=False, + theme = forms.ModelMultipleChoiceField(label=_(u'Тематики'), queryset=ThemeBlog.objects.all(), required=False, widget=forms.SelectMultiple(attrs={'style':'width: 550px'})) - slug = forms.SlugField(label=u'URL', max_length=255, min_length=1, required=False) - publish_date = forms.DateField(label=u'Дата публикации', input_formats=['%Y-%m-%d', '%d.%m.%Y'], required=False) - tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False) - logo = forms.ImageField(label=u'Лого', required=False) + slug = forms.SlugField(label=_(u'URL'), max_length=255, min_length=1, required=False) + publish_date = forms.DateField(label=_(u'Дата публикации'), input_formats=['%Y-%m-%d', '%d.%m.%Y'], required=False) + tag = forms.CharField(label=_(u'Теги'), widget=forms.HiddenInput(), required=False) + logo = forms.ImageField(label=_(u'Лого'), required=False) def __init__(self, *args, **kwargs): """ @@ -35,15 +35,15 @@ class _BlogForm(forms.Form): # uses enumerate for detect iteration number # first iteration is a default lang so it required fields required = True if lid == 0 else False - self.fields['main_title_%s' % code] = forms.CharField(label='Заголовок', required=required) - self.fields['preview_%s' % code] = forms.CharField(label='Превью', required=False, widget=CKEditorWidget) - self.fields['description_%s' % code] = forms.CharField(label='Описание', required=False, widget=CKEditorWidget) + self.fields['main_title_%s' % code] = forms.CharField(label=_(u'Заголовок'), required=required) + self.fields['preview_%s' % code] = forms.CharField(label=_(u'Превью'), required=False, widget=CKEditorWidget) + self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'), required=False, widget=CKEditorWidget) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label=_(u'Тайтл'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) def save(self, author, article=None, commit=True): @@ -107,9 +107,9 @@ class BlogForm(_BlogForm): class NewsForm(_BlogForm): type = Article.news - exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput(), required=False) - conference = forms.CharField(label=u'Конференция', widget=forms.HiddenInput(), required=False) - theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all(), required=False, + exposition = forms.CharField(label=_(u'Выставка'), widget=forms.HiddenInput(), required=False) + conference = forms.CharField(label=_(u'Конференция'), widget=forms.HiddenInput(), required=False) + theme = forms.ModelMultipleChoiceField(label=_(u'Тематики'), queryset=Theme.objects.all(), required=False, widget=forms.SelectMultiple(attrs={'style':'width: 550px'})) def save(self, author, article=None): @@ -151,12 +151,12 @@ class ArticleForm(forms.Form): save function saves data in Article object. If it doesnt exist create new object """ #users that have organiser profile - author = forms.ModelChoiceField(label='Автор',queryset=User.objects.exclude(organiser__isnull=True)) + author = forms.ModelChoiceField(label=_(u'Автор'),queryset=User.objects.exclude(organiser__isnull=True)) key = forms.CharField(required=False, widget=forms.HiddenInput()) - theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) + theme = forms.ModelMultipleChoiceField(label=_(u'Тематики'), queryset=Theme.objects.all()) #creates select input with empty choices cause it will be filled with ajax - tag = forms.MultipleChoiceField(label='Теги', required=False) + tag = forms.MultipleChoiceField(label=_(u'Теги'), required=False) article_id = forms.CharField(required=False, widget=forms.HiddenInput()) @@ -172,15 +172,15 @@ class ArticleForm(forms.Form): # uses enumerate for detect iteration number # first iteration is a default lang so it required fields required = True if lid == 0 else False - self.fields['main_title_%s' % code] = forms.CharField(label='Заголовок', required=required) - self.fields['preview_%s' % code] = forms.CharField(label='Превью', required=required, widget=CKEditorWidget) - self.fields['description_%s' % code] = forms.CharField(label='Описание', required=required, widget=CKEditorWidget) + self.fields['main_title_%s' % code] = forms.CharField(label=_(u'Заголовок'), required=required) + self.fields['preview_%s' % code] = forms.CharField(label=_(u'Превью'), required=required, widget=CKEditorWidget) + self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'), required=required, widget=CKEditorWidget) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label=_(u'Тайтл'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) def save(self, id=None): @@ -229,7 +229,7 @@ class ArticleForm(forms.Form): article = Article.objects.filter(url=translit_with_separator(main_title_ru)) if article and str(article[0].id) != id: - msg = 'Статья с таким названием уже существует' + msg = _(u'Статья с таким названием уже существует') self._errors['main_title_ru'] = ErrorList([msg]) del self.cleaned_data['main_title_ru'] diff --git a/city/admin.py b/city/admin.py index b2642e36..753c81b3 100644 --- a/city/admin.py +++ b/city/admin.py @@ -13,6 +13,7 @@ from file.forms import FileModelForm #custom views from functions.custom_views import objects_list, add_object_with_file, delete_object from functions.admin_views import AdminListView +from django.utils.translation import ugettext_lazy as _ def city_all(request): @@ -110,4 +111,4 @@ def search_city(request): class CityListView(AdminListView): template_name = 'admin/city/city_list.html' form_class = CityFilterForm - model = City \ No newline at end of file + model = City diff --git a/city/forms.py b/city/forms.py index 8843c223..82251063 100644 --- a/city/forms.py +++ b/city/forms.py @@ -14,6 +14,7 @@ from functions.translate import fill_with_signal from functions.form_check import is_positive_integer, translit_with_separator from functions.files import check_tmp_files from functions.admin_forms import AdminFilterForm +from django.utils.translation import ugettext_lazy as _ class CityForm(forms.Form): @@ -25,16 +26,16 @@ class CityForm(forms.Form): save function saves data in City object. If it doesnt exist create new object """ - country = forms.ModelChoiceField(label='Страна', + country = forms.ModelChoiceField(label=_(u'Страна'), queryset=Country.objects.filter(translations__language_code=lang()).order_by('translations__name'), empty_label=None) - population = forms.CharField(label='Население', required=False, - widget=forms.TextInput(attrs={'placeholder':'Население'})) - phone_code = forms.CharField(label='Код города', required=False, - widget=forms.TextInput(attrs={'placeholder':'Код города'})) - code_IATA = forms.ModelChoiceField(label='Код IATA', queryset=Iata.objects.all(), empty_label=None, required=False) - inflect = forms.CharField(label='Inflect', required=False) - logo = forms.ImageField(label='Logo', required=False) + population = forms.CharField(label=_(u'Население'), required=False, + widget=forms.TextInput(attrs={'placeholder':_(u'Население')})) + phone_code = forms.CharField(label=_(u'Код города'), required=False, + widget=forms.TextInput(attrs={'placeholder':_(u'Код города')})) + code_IATA = forms.ModelChoiceField(label=_(u'Код IATA'), queryset=Iata.objects.all(), empty_label=None, required=False) + inflect = forms.CharField(label=_(u'Inflect'), required=False) + logo = forms.ImageField(label=_(u'Logo'), required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) # @@ -53,20 +54,20 @@ class CityForm(forms.Form): # uses enumerate for detect iteration number # first iteration is a default lang so it required fields required = True if lid == 0 else False - self.fields['name_%s' % code] = forms.CharField(label='Название', required=required) - self.fields['region_%s' % code] = forms.CharField(label='Регион', required=False) - self.fields['description_%s' % code] = forms.CharField(label='Описание', + self.fields['name_%s' % code] = forms.CharField(label=_(u'Название'), required=required) + self.fields['region_%s' % code] = forms.CharField(label=_(u'Регион'), required=False) + self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'), required=False, widget=CKEditorWidget) - self.fields['famous_places_%s' % code] = forms.CharField(label='Знаменитые места', + self.fields['famous_places_%s' % code] = forms.CharField(label=_(u'Знаменитые места'), required=False, widget=CKEditorWidget()) - self.fields['shoping_%s' % code] = forms.CharField(label='Шопинг', required=False, widget=CKEditorWidget()) - self.fields['transport_%s' % code] = forms.CharField(label='Транспорт', required=False, widget=CKEditorWidget()) + self.fields['shoping_%s' % code] = forms.CharField(label=_(u'Шопинг'), required=False, widget=CKEditorWidget()) + self.fields['transport_%s' % code] = forms.CharField(label=_(u'Транспорт'), required=False, widget=CKEditorWidget()) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label=_(u'Тайтл'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) @@ -148,7 +149,7 @@ class CityForm(forms.Form): if phone_code.isdigit(): return phone_code else: - raise ValidationError('Введите правильный телефонный код') + raise ValidationError(_(u'Введите правильный телефонный код')) def clean_population(self): """ @@ -168,7 +169,7 @@ class CityDeleteForm(forms.ModelForm): class CityFilterForm(AdminFilterForm): country = forms.ChoiceField(choices=[('', '')]+[(item.id, item.name) for item in Country.objects.all()], required=False, - label='Страна') + label=_(u'Страна')) model = City def filter(self): diff --git a/city/models.py b/city/models.py index db53599e..749facc0 100644 --- a/city/models.py +++ b/city/models.py @@ -28,7 +28,7 @@ class City(TranslatableModel): catalog = '/city/' services = BitField(flags=flags) url = models.SlugField(verbose_name=_(u'Url'), unique=True) - logo = models.ImageField(verbose_name='Logo', upload_to='city/logo/', blank=True, max_length=255) + logo = models.ImageField(verbose_name=_(u'Logo'), upload_to='city/logo/', blank=True, max_length=255) old_url = models.CharField(verbose_name=_(u'Url старой бд'), max_length=55) # inflect name for russian language. example- в Москве inflect = models.CharField(verbose_name=_(u'Склонение'), max_length=255, blank=True) @@ -145,4 +145,4 @@ class Hotel(TranslatableModel): pre_save.connect(pre_save_handler, sender=City) post_save.connect(post_save_handler, sender=City) -post_save.connect(post_save_handler, sender=Hotel) \ No newline at end of file +post_save.connect(post_save_handler, sender=Hotel) diff --git a/city/search_indexes.py b/city/search_indexes.py index 8d54a854..e931270a 100644 --- a/city/search_indexes.py +++ b/city/search_indexes.py @@ -33,4 +33,4 @@ class CountryIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin): return self.get_model().used.all() def get_updated_field(self): - return 'modified' \ No newline at end of file + return 'modified' diff --git a/company/admin.py b/company/admin.py index 525d0e23..c6c866d0 100644 --- a/company/admin.py +++ b/company/admin.py @@ -16,6 +16,7 @@ from functions.custom_views import (add_object_with_file, delete_object, # models and forms from models import Company from theme.models import Tag +from django.utils.translation import ugettext_lazy as _ def company_all(request): diff --git a/company/forms.py b/company/forms.py index ad2ff764..3c6f5d4e 100644 --- a/company/forms.py +++ b/company/forms.py @@ -27,30 +27,30 @@ class CompanyForm(forms.Form): save function saves data in Company object. If it doesnt exist create new object """ - url = forms.CharField(label='URL', widget=forms.TextInput(attrs={'placeholder': 'Введите URL'})) + url = forms.CharField(label=_(u'URL'), widget=forms.TextInput(attrs={'placeholder': _(u'Введите URL')})) - country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None) - theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) + country = forms.ModelChoiceField(label=_(u'Страна'), queryset=Country.objects.all(), empty_label=None) + theme = forms.ModelMultipleChoiceField(label=_(u'Тематики'), queryset=Theme.objects.all()) #creates select input with empty choices cause it will be filled with ajax - city = forms.ChoiceField(label='Город', choices=[('','')]) - tag = forms.MultipleChoiceField(label='Теги', required=False) + city = forms.ChoiceField(label=_(u'Город'), choices=[('','')]) + tag = forms.MultipleChoiceField(label=_(u'Теги'), required=False) - staff_number = forms.CharField(label='Количество сотрудников', required=False, - widget=forms.TextInput(attrs={'placeholder': 'Количество сотрудников'})) + staff_number = forms.CharField(label=_(u'Количество сотрудников'), required=False, + widget=forms.TextInput(attrs={'placeholder': _(u'Количество сотрудников')})) #uses locationwidget - address = forms.CharField(label='Адрес', required=False, widget=LocationWidget) + address = forms.CharField(label=_(u'Адрес'), required=False, widget=LocationWidget) - phone = forms.CharField(label='Телефон', required=False, - widget=forms.TextInput(attrs={'placeholder': 'Введите телефон'})) + phone = forms.CharField(label=_(u'Телефон'), required=False, + widget=forms.TextInput(attrs={'placeholder': _(u'Введите телефон')})) fax = forms.CharField(label='Факс', required=False, - widget=forms.TextInput(attrs={'placeholder': 'Введите факс'})) - web_page = forms.CharField(label='Веб-сайт', required=False, - widget=forms.TextInput(attrs={'placeholder': 'Введите адрес сайта'})) - email = forms.CharField(label='Email', required=False, - widget=forms.TextInput(attrs={'placeholder': 'Введите email'})) - social = forms.CharField(label='Социальные страници', required=False) - foundation = forms.CharField(label='Год основания', required=False, - widget=forms.TextInput(attrs={'placeholder': 'Год основания'})) + widget=forms.TextInput(attrs={'placeholder': _(u'Введите факс')})) + web_page = forms.CharField(label=_(u'Веб-сайт'), required=False, + widget=forms.TextInput(attrs={'placeholder': _(u'Введите адрес сайта')})) + email = forms.CharField(label=_(u'Email'), required=False, + widget=forms.TextInput(attrs={'placeholder': _(u'Введите email')})) + social = forms.CharField(label=_(u'Социальные страници'), required=False) + foundation = forms.CharField(label=_(u'Год основания'), required=False, + widget=forms.TextInput(attrs={'placeholder': _(u'Год основания')})) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) # @@ -69,18 +69,18 @@ class CompanyForm(forms.Form): # uses enumerate for detect iteration number # first iteration is a default lang so it required fields required = True if lid == 0 else False - self.fields['name_%s' % code] = forms.CharField(label='Название', required=required) - self.fields['description_%s' % code] = forms.CharField(label='Описание', + self.fields['name_%s' % code] = forms.CharField(label=_(u'Название'), required=required) + self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'), required=False, widget=CKEditorWidget) - self.fields['specialization_%s' % code] = forms.CharField(label='Специализация', required=False) - self.fields['address_inf_%s' % code] = forms.CharField(label='Доп инф по адресу', + self.fields['specialization_%s' % code] = forms.CharField(label=_(u'Специализация'), required=False) + self.fields['address_inf_%s' % code] = forms.CharField(label=_(u'Доп инф по адресу'), required=False, widget=CKEditorWidget) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label=_(u'Тайтл'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) @@ -139,7 +139,7 @@ class CompanyForm(forms.Form): company = Company.objects.filter(url=translit_with_separator(url)) if company and str(company[0].id) != id: - msg = 'Такой урл уже занят' + msg = _(u'Такой урл уже занят') self._errors['url'] = ErrorList([msg]) del self.cleaned_data['url'] @@ -184,7 +184,7 @@ class CompanyForm(forms.Form): if phone.isdigit(): return phone else: - raise ValidationError('Введите правильный телефон') + raise ValidationError(_(u'Введите правильный телефон')) def clean_fax(self): """ @@ -203,7 +203,8 @@ class CompanyForm(forms.Form): if fax.isdigit(): return fax else: - raise ValidationError('Введите правильный факс') + raise ValidationError(_(u'Введите правильный факс')) + class CompanyDeleteForm(forms.ModelForm): id = forms.CharField(widget=forms.HiddenInput()) @@ -212,6 +213,7 @@ class CompanyDeleteForm(forms.ModelForm): model = Company fields = ('id',) + class CompanyFormClient(forms.Form): # translated fields @@ -224,18 +226,18 @@ class CompanyFormClient(forms.Form): country = forms.ModelChoiceField(label=_(u'Страна'), queryset=Country.objects.all(), empty_label=None) city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput()) theme = forms.ModelMultipleChoiceField(label=_(u'Тематики'), queryset=Theme.objects.all()) - tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False) + tag = forms.CharField(label=_(u'Теги'), widget=forms.HiddenInput(), required=False) - phone = forms.CharField(label='Телефон', required=False) - fax = forms.CharField(label='Факс', required=False) - web_page = forms.URLField(label='Веб-сайт', required=False) - email = forms.EmailField(label='Email', required=False) + phone = forms.CharField(label=_(u'Телефон'), required=False) + fax = forms.CharField(label=_(u'Факс'), required=False) + web_page = forms.URLField(label=_(u'Веб-сайт'), required=False) + email = forms.EmailField(label=_(u'Email'), required=False) foundation = forms.IntegerField(label=_(u'Год основания'), required=False) staff_number = forms.IntegerField(label=_(u'Количество сотрудников'), required=False) vk = forms.URLField(label=_(u'в контакте'), required=False) - twitter = forms.URLField(label=u'Twitter', required=False) - facebook = forms.URLField(label=u'Facebook', required=False) - linkedin = forms.URLField(label=u'Linkedin', required=False) + twitter = forms.URLField(label=_(u'Twitter'), required=False) + facebook = forms.URLField(label=_(u'Facebook'), required=False) + linkedin = forms.URLField(label=_(u'Linkedin'), required=False) def __init__(self, *args, **kwargs): @@ -279,7 +281,6 @@ class CreateCompanyForm(forms.Form): return company - def clean_url(self): url = self.cleaned_data['url'] url = url.replace('http://expomap.ru/members/', '') @@ -296,4 +297,4 @@ class CreateCompanyForm(forms.Form): return translit_with_separator(url) class CompanyFilterForm(AdminFilterForm): - model = Company \ No newline at end of file + model = Company diff --git a/company/models.py b/company/models.py index 81e5f3d0..89487958 100644 --- a/company/models.py +++ b/company/models.py @@ -32,34 +32,34 @@ class Company(TranslatableModel, ExpoMixin, GetURLorPK): url = models.SlugField(max_length=255) #relations - creator = models.ForeignKey('accounts.User', verbose_name='Создатель', related_name='created_company', + creator = models.ForeignKey('accounts.User', verbose_name=_(u'Создатель'), related_name='created_company', blank=True, null=True) - theme = models.ManyToManyField('theme.Theme', verbose_name='Отрасль', + theme = models.ManyToManyField('theme.Theme', verbose_name=_(u'Отрасль'), blank=True, null=True, related_name='companies') - tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', blank=True, null=True, related_name='companies') - country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, + tag = models.ManyToManyField('theme.Tag', verbose_name=_(u'Теги'), blank=True, null=True, related_name='companies') + country = models.ForeignKey('country.Country', verbose_name=_(u'Страна'), blank=True, null=True, on_delete=models.PROTECT, related_name='companies') - city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, + city = models.ForeignKey('city.City', verbose_name=_(u'Город'), blank=True, null=True, on_delete=models.PROTECT, related_name='companies') #address. uses LocationField. saves data in json format address = LocationField(verbose_name='Адрес', blank=True) - staff_number = models.CharField(verbose_name='Количество сотрудников', max_length=50, blank=True) - phone = models.BigIntegerField(verbose_name='Телефон', blank=True, null=True) - fax = models.BigIntegerField(verbose_name='Факс', blank=True, null=True) - web_page = models.CharField(verbose_name='Веб-сайт',max_length=255, blank=True) - email = models.EmailField(verbose_name='Email', blank=True) + staff_number = models.CharField(verbose_name=_(u'Количество сотрудников'), max_length=50, blank=True) + phone = models.BigIntegerField(verbose_name=_(u'Телефон'), blank=True, null=True) + fax = models.BigIntegerField(verbose_name=_(u'Факс'), blank=True, null=True) + web_page = models.CharField(verbose_name=_(u'Веб-сайт'),max_length=255, blank=True) + email = models.EmailField(verbose_name=_(u'Email'), blank=True) facebook = models.URLField(verbose_name=_(u'Facebook'), blank=True) twitter = models.URLField(verbose_name=_(u'Twitter'), blank=True) linkedin = models.URLField(verbose_name=_(u'LinkedIn'), blank=True) vk = models.URLField(verbose_name=_(u'В контакте'), blank=True) - foundation = models.PositiveIntegerField(verbose_name='Год основания', blank=True, null=True) + foundation = models.PositiveIntegerField(verbose_name=_(u'Год основания'), blank=True, null=True) #translation fields translations = TranslatedFields( - name = models.CharField(verbose_name='Название компании', max_length=255), - specialization = models.CharField(verbose_name='Специализация', max_length=255, blank=True), - description = models.TextField(verbose_name='О компании', blank=True), - address_inf = models.TextField(verbose_name='Доп инф по адресу', blank=True), + name = models.CharField(verbose_name=_(u'Название компании'), max_length=255), + specialization = models.CharField(verbose_name=_(u'Специализация'), max_length=255, blank=True), + description = models.TextField(verbose_name=_(u'О компании'), blank=True), + address_inf = models.TextField(verbose_name=_(u'Доп инф по адресу'), blank=True), #-----meta title = models.CharField(max_length=255), descriptions = models.CharField(max_length=255), diff --git a/conference/forms.py b/conference/forms.py index 49a48de8..685db687 100644 --- a/conference/forms.py +++ b/conference/forms.py @@ -4,6 +4,7 @@ from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.forms.util import ErrorList from django.core.validators import validate_email, URLValidator +from django.utils.translation import ugettext as _ #models from models import Conference, TimeTable, CURRENCY, Statistic, BIT_AUDIENCE from country.models import Country @@ -34,51 +35,51 @@ class ConferenceCreateForm(forms.Form): save function saves data in Conference object. If it doesnt exist create new object """ - PERIODIC = ((0, u'Не выбрано'), (1.0, u'Ежегодно'), (2.0, u'2 раза в год'), (3.0, u'3 раза в год'), - (4.0, u'4 раза в год'), (5.0, u'5 раз в год'), (0.5, u'Раз в 2 года'),(0.33, u'Раз в 3 года'), - (0.25, u'Раз в 4 года'), (0.2, u'Раз в 5 лет')) + PERIODIC = ((0, _(u'Не выбрано')), (1.0, _(u'Ежегодно')), (2.0, _(u'2 раза в год')), (3.0, _(u'3 раза в год')), + (4.0, _(u'4 раза в год')), (5.0, _(u'5 раз в год')), (0.5, _(u'Раз в 2 года')),(0.33, _(u'Раз в 3 года')), + (0.25, _(u'Раз в 4 года')), (0.2, _(u'Раз в 5 лет'))) public = [(item1, item2) for item1, item2 in BIT_AUDIENCE] currencies = [(item, item) for item in CURRENCY] - data_begin = forms.DateField(label=u'Дата начала', input_formats=['%Y-%m-%d', '%d.%m.%Y']) - data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y']) - logo = forms.ImageField(label='Logo', required=False) + data_begin = forms.DateField(label=_(u'Дата начала'), input_formats=['%Y-%m-%d', '%d.%m.%Y']) + data_end = forms.DateField(label=_(u'Дата окончания'), input_formats=['%Y-%m-%d', '%d.%m.%Y']) + logo = forms.ImageField(label=_(u'Logo'), required=False) #organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False, # choices=[(item.id, item.name) for item in Organiser.objects.language().all()]) - org = forms.CharField(required=False, label=u'Организатор') - country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()]) - theme = forms.MultipleChoiceField(label='Тематики', + org = forms.CharField(required=False, label=_(u'Организатор')) + country = forms.ChoiceField(label=_(u'Страна'), choices=[(c.id, c.name) for c in Country.objects.all()]) + theme = forms.MultipleChoiceField(label=_(u'Тематики'), choices=[(item.id, item.name) for item in Theme.objects.language().all()]) - place = forms.ChoiceField(label=u'Место проведения', required=False, + place = forms.ChoiceField(label=_(u'Место проведения'), required=False, choices=places) - place_alt = forms.CharField(label = u"Альтернативное название места", required=False) + place_alt = forms.CharField(label = _(u"Альтернативное название места"), required=False) #creates select input with empty choices cause it will be filled with ajax - city = forms.CharField(label=u'Город', widget=forms.HiddenInput()) - tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False) - - periodic = forms.ChoiceField(label=u'Периодичность', choices=PERIODIC, required=False) - audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False) - - web_page = forms.CharField(label='Веб страница', required=False) - link = forms.CharField(label='Линк на регистрацию', required=False) - foundation_year = forms.CharField(label='Год основания', required=False) - members = forms.CharField(label='Участники', required=False) - visitors = forms.CharField(label='Посетители', required=False) - discount = forms.CharField(label='Cкидка(%)', required=False) + city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput()) + tag = forms.CharField(label=_(u'Теги'), widget=forms.HiddenInput(), required=False) + + periodic = forms.ChoiceField(label=_(u'Периодичность'), choices=PERIODIC, required=False) + audience = forms.MultipleChoiceField(label=_(u'Аудитория'), choices=public, initial='', required=False) + + web_page = forms.CharField(label=_(u'Веб страница'), required=False) + link = forms.CharField(label=_(u'Линк на регистрацию'), required=False) + foundation_year = forms.CharField(label=_(u'Год основания'), required=False) + members = forms.CharField(label=_(u'Участники'), required=False) + visitors = forms.CharField(label=_(u'Посетители'), required=False) + discount = forms.CharField(label=_(u'Cкидка(%)'), required=False) # - currency = forms.ChoiceField(label='Валюта', choices=currencies, required=False) - tax = forms.BooleanField(label='Налог включен', initial=True, required=False) - min_price = forms.CharField(label='Минимальная цена', required=False) - max_price = forms.CharField(label='Максимальная цена', required=False) - expohit = forms.BooleanField(label='Expohit', required=False) - canceled = forms.BooleanField(label='Отменена', required=False) - moved = forms.BooleanField(label='Перенесена', required=False) - quality_label = forms.MultipleChoiceField(label='Тип', required=False, + currency = forms.ChoiceField(label=_(u'Валюта'), choices=currencies, required=False) + tax = forms.BooleanField(label=_(u'Налог включен'), initial=True, required=False) + min_price = forms.CharField(label=_(u'Минимальная цена'), required=False) + max_price = forms.CharField(label=_(u'Максимальная цена'), required=False) + expohit = forms.BooleanField(label=_(u'Expohit'), required=False) + canceled = forms.BooleanField(label=_(u'Отменена'), required=False) + moved = forms.BooleanField(label=_(u'Перенесена'), required=False) + quality_label = forms.MultipleChoiceField(label=_(u'Тип'), required=False, choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')], widget=forms.CheckboxSelectMultiple()) @@ -97,23 +98,23 @@ class ConferenceCreateForm(forms.Form): # uses enumerate for detect iteration number # first iteration is a default lang so it required fields required = True if lid == 0 else False - self.fields['name_%s' % code] = forms.CharField(label='Название', required=required) - self.fields['main_title_%s' % code] = forms.CharField(label='Краткое описание', + self.fields['name_%s' % code] = forms.CharField(label=_(u'Название'), required=required) + self.fields['main_title_%s' % code] = forms.CharField(label=_(u'Краткое описание'), required=False, widget=CKEditorWidget) - self.fields['description_%s' % code] = forms.CharField(label='Описание', + self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'), required=False, widget=CKEditorWidget) - self.fields['time_%s' % code] = forms.CharField(label='Время работы', + self.fields['time_%s' % code] = forms.CharField(label=_(u'Время работы'), required=False, widget=CKEditorWidget) - self.fields['main_themes_%s' % code] = forms.CharField(label='Основные темы', + self.fields['main_themes_%s' % code] = forms.CharField(label=_(u'Основные темы'), required=False, widget=CKEditorWidget) - self.fields['discount_description_%s' % code] = forms.CharField(label='Описание скидки', + self.fields['discount_description_%s' % code] = forms.CharField(label=_(u'Описание скидки'), required=False, widget=CKEditorWidget) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label=_(u'Тайтл'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) @@ -313,9 +314,9 @@ class ConferenceChangeForm(ConferenceCreateForm): add some fields to ConferenceCreateForm """ - organiser = forms.ModelMultipleChoiceField(label='Организаторы', queryset=Organiser.objects.all(), required=False) - company = forms.ModelMultipleChoiceField(label='Компании', queryset=Company.objects.all(), required=False) - users = forms.ModelMultipleChoiceField(label='Пользователи', queryset=User.objects.all(), required=False) + organiser = forms.ModelMultipleChoiceField(label=_(u'Организаторы'), queryset=Organiser.objects.all(), required=False) + company = forms.ModelMultipleChoiceField(label=_(u'Компании'), queryset=Company.objects.all(), required=False) + users = forms.ModelMultipleChoiceField(label=_(u'Пользователи'), queryset=User.objects.all(), required=False) class ConferenceDeleteForm(forms.ModelForm): @@ -355,8 +356,8 @@ class TimeTableForm(forms.Form): Create TimeTable form day field must save automatically """ - begin = forms.DateTimeField(label='Время начала') - end = forms.DateTimeField(label='Время окончания') + begin = forms.DateTimeField(label=_(u'Время начала')) + end = forms.DateTimeField(label=_(u'Время окончания')) def __init__(self, *args, **kwargs): """ @@ -378,7 +379,7 @@ class TimeTableForm(forms.Form): class ConferenceFilterForm(AdminFilterForm): - created = forms.DateField(required=False, label='Дата создания') + created = forms.DateField(required=False, label=_(u'Дата создания')) model = Conference def filter(self): diff --git a/conference/models.py b/conference/models.py index e9e3ad43..a2b4dd9e 100644 --- a/conference/models.py +++ b/conference/models.py @@ -47,27 +47,27 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): url = models.SlugField(unique=True, max_length=255) old_url = models.SlugField(unique=True, max_length=255) - data_begin = models.DateField(verbose_name='Дата начала') - data_end = models.DateField(verbose_name='Дата окончания') + data_begin = models.DateField(verbose_name=_(u'Дата начала')) + data_end = models.DateField(verbose_name=_(u'Дата окончания')) services = BitField(flags=flags) #relations - country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT, + country = models.ForeignKey('country.Country', verbose_name=_(u'Страна'), on_delete=models.PROTECT, related_name='conference_country') - city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT, + city = models.ForeignKey('city.City', verbose_name=_(u'Город'), on_delete=models.PROTECT, related_name='conference_city') - place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения', + place = models.ForeignKey('place_conference.PlaceConference', verbose_name=_(u'Место проведения'), blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place') place_alt = models.CharField(blank=True, null=True, max_length=255) # alternative for object place - theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики', + theme = models.ManyToManyField('theme.Theme', verbose_name=_(u'Тематики'), related_name='conference_themes') - tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', + tag = models.ManyToManyField('theme.Tag', verbose_name=_(u'Теги'), blank=True, null=True, related_name='conference_tags') - organiser = models.ManyToManyField('organiser.Organiser', verbose_name='Организатор', + organiser = models.ManyToManyField('organiser.Organiser', verbose_name=_(u'Организатор'), blank=True, null=True, related_name='conference_organisers') org = models.CharField(max_length=255, blank=True, null=True) - company = models.ManyToManyField('company.Company', verbose_name='Компании', + company = models.ManyToManyField('company.Company', verbose_name=_(u'Компании'), blank=True, null=True, related_name='conference_companies') - users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки', + users = models.ManyToManyField('accounts.User', verbose_name=_(u'Посетители выставки'), blank=True, null=True, related_name='conference_users') photogallery = models.ForeignKey('photologue.Gallery', blank=True, null=True, on_delete=models.SET_NULL) logo = models.ImageField(verbose_name='Logo', upload_to='conference/logo/', blank=True) @@ -75,17 +75,17 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): quality_label = BitField(flags=['ufi', 'rsva', 'exporating']) - periodic = models.FloatField(verbose_name='Переодичность', blank=True, null=True) + periodic = models.FloatField(verbose_name=_(u'Переодичность'), blank=True, null=True) audience = BitField(flags=[k for k, v in BIT_AUDIENCE]) - web_page = models.CharField(verbose_name='Вебсайт', max_length=255, blank=True) - link = models.CharField(verbose_name='Линк на регистрацию', max_length=255, blank=True) - discount = models.PositiveIntegerField(verbose_name='Скидка', blank=True, null=True) + web_page = models.CharField(verbose_name=_(u'Вебсайт'), max_length=255, blank=True) + link = models.CharField(verbose_name=_(u'Линк на регистрацию'), max_length=255, blank=True) + discount = models.PositiveIntegerField(verbose_name=_(u'Скидка'), blank=True, null=True) # currency = EnumField(values=CURRENCY, default='USD') - tax = models.BooleanField(verbose_name='Налог', default=1) - min_price = models.PositiveIntegerField(verbose_name='Минимальная цена', blank=True, null=True) - max_price = models.PositiveIntegerField(verbose_name='Максимальная цена', blank=True, null=True) + tax = models.BooleanField(verbose_name=_(u'Налог'), default=1) + min_price = models.PositiveIntegerField(verbose_name=_(u'Минимальная цена'), blank=True, null=True) + max_price = models.PositiveIntegerField(verbose_name=_(u'Максимальная цена'), blank=True, null=True) #administrator can cancel conference expohit = models.BooleanField(verbose_name='Expohit', default=0) canceled_by_administrator = models.BooleanField(default=0) @@ -97,17 +97,17 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id') note = generic.GenericRelation('note.Note', content_type_field='content_type', object_id_field='object_id') # statistic - foundation_year = models.PositiveIntegerField(verbose_name='Год основания', blank=True, null=True) - visitors = models.PositiveIntegerField(verbose_name='Посетитеил', blank=True, null=True) - members = models.PositiveIntegerField(verbose_name='Участники', blank=True, null=True) + foundation_year = models.PositiveIntegerField(verbose_name=_(u'Год основания'), blank=True, null=True) + visitors = models.PositiveIntegerField(verbose_name=_(u'Посетитеил'), blank=True, null=True) + members = models.PositiveIntegerField(verbose_name=_(u'Участники'), blank=True, null=True) #translated fields translations = TranslatedFields( - name = models.CharField(verbose_name='Название', max_length=255), - main_title=models.TextField(verbose_name='Краткое описание', blank=True), - description=models.TextField(verbose_name='Описание', blank=True), - main_themes=models.TextField(verbose_name='Основные темы', blank=True), - time=models.TextField(verbose_name='Время работы', blank=True), - discount_description=models.TextField(verbose_name='Описание скидки', blank=True), + name = models.CharField(verbose_name=_(u'Название'), max_length=255), + main_title=models.TextField(verbose_name=_(u'Краткое описание'), blank=True), + description=models.TextField(verbose_name=_(u'Описание'), blank=True), + main_themes=models.TextField(verbose_name=_(u'Основные темы'), blank=True), + time=models.TextField(verbose_name=_(u'Время работы'), blank=True), + discount_description=models.TextField(verbose_name=_(u'Описание скидки'), blank=True), #-----meta data title=models.CharField(max_length=250), descriptions=models.CharField(max_length=250), @@ -208,11 +208,11 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): class Statistic(TranslatableModel): conference = models.ForeignKey(Conference, related_name='statistic') - year = models.PositiveIntegerField(verbose_name='Год') - members = models.PositiveIntegerField(verbose_name='Посетители', blank=True, null=True) - visitors = models.PositiveIntegerField(verbose_name='Участники', blank=True, null=True) - area = models.PositiveIntegerField(verbose_name='Площадь', blank=True, null=True) - countries_number = models.PositiveIntegerField(verbose_name='Количество стран', blank=True, null=True) + year = models.PositiveIntegerField(verbose_name=_(u'Год')) + members = models.PositiveIntegerField(verbose_name=_(u'Посетители'), blank=True, null=True) + visitors = models.PositiveIntegerField(verbose_name=_(u'Участники'), blank=True, null=True) + area = models.PositiveIntegerField(verbose_name=_(u'Площадь'), blank=True, null=True) + countries_number = models.PositiveIntegerField(verbose_name=_(u'Количество стран'), blank=True, null=True) translations = TranslatedFields( countries = models.TextField(blank=True) @@ -228,8 +228,8 @@ class TimeTable(TranslatableModel): """ conference = models.ForeignKey(Conference, related_name='business_program') - begin = models.DateTimeField(verbose_name='Начало') - end = models.DateTimeField(verbose_name='Конец') + begin = models.DateTimeField(verbose_name=_(u'Начало')) + end = models.DateTimeField(verbose_name=_(u'Конец')) timetable_organiser = models.ForeignKey('organiser.Organiser', null=True, blank=True, related_name='conf_timetable') # @@ -237,10 +237,10 @@ class TimeTable(TranslatableModel): modified = models.DateTimeField(auto_now=True) #translated fields translations = TranslatedFields( - name = models.CharField(verbose_name='Название программы', max_length=255, blank=True), - programe = models.TextField(verbose_name='Программа'), - speaker = models.CharField(verbose_name='Спикеры', max_length=255, blank=True), - place = models.CharField(verbose_name='Место проведения', max_length=255, blank=True) + name = models.CharField(verbose_name=_(u'Название программы'), max_length=255, blank=True), + programe = models.TextField(verbose_name=_(u'Программа')), + speaker = models.CharField(verbose_name=_(u'Спикеры'), max_length=255, blank=True), + place = models.CharField(verbose_name=_(u'Место проведения'), max_length=255, blank=True) ) def to_dict(self): diff --git a/conference/views.py b/conference/views.py index b192cb53..1e7e39c8 100644 --- a/conference/views.py +++ b/conference/views.py @@ -562,9 +562,10 @@ def send_to_organiser(request, slug): email = request.POST.get('person') phone = request.POST.get('phone', '') question = request.POST.get('question', '') - text = u"конференция: %s\n Контактное лицо:%s\nEmail: %s\nтелефон:%s\n вопрос:%s"%(exposition.name, name, email, - phone, question) - msg = EmailMessage(u'Проплаченная конференция', text, settings.DEFAULT_FROM_EMAIL, [mail_send]) + data = {'expo_name': exposition.name, 'name': name, 'email': email, + 'phone': phone, 'question': question} + text = _(u"конференция: %(expo_name)s\n Контактное лицо:%(name)s\nEmail: %(email)s\nтелефон:%(phone)s\n вопрос:%(question)s") % data + msg = EmailMessage(_(u'Проплаченная конференция'), text, settings.DEFAULT_FROM_EMAIL, [mail_send]) msg.content_subtype = "html" msg.send() redirect_to = '%sservice/thanks/'%exposition.get_permanent_url() diff --git a/core/forms.py b/core/forms.py index d00f080e..fe61cd31 100644 --- a/core/forms.py +++ b/core/forms.py @@ -2,6 +2,7 @@ from django import forms from django.conf import settings from django.core.mail import send_mail +from django.utils.translation import ugettext as _ from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference from django.utils.translation import ugettext_lazy as _ @@ -9,6 +10,7 @@ from haystack.query import SearchQuerySet, EmptySearchQuerySet from hvad.forms import TranslatableModelForm from models import Page + class PlaceSearchForm(forms.Form): q = forms.CharField(label=_(u'Поиск'), required=False) w = forms.CharField(label=_(u'Где'), required=False) diff --git a/core/models.py b/core/models.py index 56d75875..c899dabe 100644 --- a/core/models.py +++ b/core/models.py @@ -2,6 +2,7 @@ from django.contrib.syndication.views import Feed from django.shortcuts import get_object_or_404 from django.db import models +from django.utils.translation import ugettext as _ from exposition.models import Exposition import copy @@ -18,9 +19,9 @@ EXPO_ON_PAGE = 10 # nearest expositions at all class LatestExpositions(Feed): - title = u"Ближайшие выставки на expomap.ru" + title = _(u"Ближайшие выставки на expomap.ru") link = '/rss/latest/' - description = u'Подписывайтесь на наш RSS-канал' + description = _(u'Подписывайтесь на наш RSS-канал') def items(self): return Exposition.enable.upcoming()[:EXPO_ON_PAGE] @@ -44,7 +45,7 @@ class CountryFeeds(Feed): return get_object_or_404(Country, url=slug) def title(self, obj): - return u"Ближайшие выставки %s:" % obj.inflect + return _(u"Ближайшие выставки %(obj)s:") % {'obj': obj.inflect} def link(self,obj): return obj.get_permanent_url() @@ -63,7 +64,7 @@ class CityFeeds(Feed): return get_object_or_404(City, url=slug) def title(self, obj): - return u"Ближайшие выставки в %s: " % obj.inflect + return _(u"Ближайшие выставки в %(obj)s: ") % {'obj': obj.inflect} def link(self,obj): return obj.get_permanent_url() @@ -82,7 +83,7 @@ class ThemeFeeds(Feed): return get_object_or_404(Theme, url=slug) def title(self, obj): - return u"Ближайшие выставки %s: " % obj.inflect + return _(u"Ближайшие выставки %(obj)s: ") % {'obj': obj.inflect} def link(self,obj): return obj.url diff --git a/core/simple_views.py b/core/simple_views.py index 5f556f4a..78ea6797 100644 --- a/core/simple_views.py +++ b/core/simple_views.py @@ -4,7 +4,7 @@ from django.views.generic import TemplateView from django.core.mail import EmailMessage from django.http import HttpResponse from django.conf import settings - +from django.utils.translation import ugettext as _ class SeminarLendingView(TemplateView): @@ -14,30 +14,32 @@ class SeminarLendingView(TemplateView): def send_to_organiser(request): mail_send = 'expomap@mail.ru' - fname = request.POST.get('name') - lname = request.POST.get('surname') - email = request.POST.get('email', '') - company = request.POST.get('company', '') - office = request.POST.get('office', '') - phone = request.POST.get('phone', '') + data = { + 'fname': request.POST.get('name'), + 'lname': request.POST.get('surname'), + 'email': request.POST.get('email', ''), + 'company': request.POST.get('company', ''), + 'office': request.POST.get('office', ''), + 'phone': request.POST.get('phone', ''), + } title = request.POST.get('type', '') - text = u"""Имя: %s; - Фамилия:%s; - Email: %s; - Телефон: %s; - компния:%s; - должность: %s"""%(fname, lname, email, phone, company, office) + text = _(u"""Имя: %(fname)s; + Фамилия:%(lname)s; + Email: %(email)s; + Телефон: %(phone)s; + компния: %(company)s; + должность: %(office)s""") % data msg = EmailMessage(title, text, settings.DEFAULT_FROM_EMAIL, [mail_send]) msg.content_subtype = "html" msg.send() redirect_to = '/service/thanks/' if title.endswith(u'семинар'): - message = u"""Мы получили Ваш запрос и очень рады, что Вам интересно участие в семинаре Expomap. Если места еще есть, мы пришлем Вам приглашение на указанную Вами электронную почту. - Увидимся на welcome-coffee ☺""" + message = _(u"""Мы получили Ваш запрос и очень рады, что Вам интересно участие в семинаре Expomap. Если места еще есть, мы пришлем Вам приглашение на указанную Вами электронную почту. + Увидимся на welcome-coffee ☺""") else: - message = u"""Благодарим за интерес к нашему семинару! За несколько дней до мероприятия мы пришлем Вам ссылку для подключения к онлайн-трансляции!""" + message = _(u"""Благодарим за интерес к нашему семинару! За несколько дней до мероприятия мы пришлем Вам ссылку для подключения к онлайн-трансляции!""") return HttpResponse(json.dumps({'success':True, 'redirect_to': redirect_to, 'message': message}), content_type='application/json') diff --git a/country/forms.py b/country/forms.py index 67193e43..92897e98 100644 --- a/country/forms.py +++ b/country/forms.py @@ -5,6 +5,8 @@ from ckeditor.widgets import CKEditorWidget from tinymce.widgets import TinyMCE from django.core.exceptions import ValidationError from django.forms.util import ErrorList +from django.utils.translation import ugettext as _ + #models from models import Country, City from directories.models import Language, Currency, Iata @@ -42,20 +44,20 @@ class CountryForm(forms.Form): save function saves data in Country object. If it doesnt exist create new object """ # - currency = forms.ModelMultipleChoiceField(label='Валюты', queryset=Currency.objects.all(), required=False) - language = forms.ModelMultipleChoiceField(label='Языки', queryset=Language.objects.all(), required=False) + currency = forms.ModelMultipleChoiceField(label=_(u'Валюты'), queryset=Currency.objects.all(), required=False) + language = forms.ModelMultipleChoiceField(label=_(u'Языки'), queryset=Language.objects.all(), required=False) # - population = forms.CharField(label='Население(млн)', required=False, - widget=forms.TextInput(attrs={'placeholder':'Население(млн)'})) + population = forms.CharField(label=_(u'Население(млн)'), required=False, + widget=forms.TextInput(attrs={'placeholder':_(u'Население(млн)')})) teritory = forms.CharField(label='Территория(км2)', required=False, - widget=forms.TextInput(attrs={'placeholder':'Територия(км2)'}))# km2 - timezone = forms.ChoiceField(label='Часовые пояса', required=False, choices=tz, initial=99) - phone_code = forms.CharField(label='Код страны', required=False, - widget=forms.TextInput(attrs={'placeholder':'Код страны'})) - time_delivery = forms.CharField(label='Срок выдачи', required=False, - widget=forms.TextInput(attrs={'placeholder':'Срок выдачи'})) + widget=forms.TextInput(attrs={'placeholder':_(u'Територия(км2)')}))# km2 + timezone = forms.ChoiceField(label=_(u'Часовые пояса'), required=False, choices=tz, initial=99) + phone_code = forms.CharField(label=_(u'Код страны'), required=False, + widget=forms.TextInput(attrs={'placeholder':_(u'Код страны')})) + time_delivery = forms.CharField(label=_(u'Срок выдачи'), required=False, + widget=forms.TextInput(attrs={'placeholder':_(u'Срок выдачи')})) - logo = forms.ImageField(label='Logo', required=False) + logo = forms.ImageField(label=_(u'Logo'), required=False) #services = forms.MultipleChoiceField(label='Сервисы', required=False, choices=); #field for comparing tmp files @@ -82,33 +84,33 @@ class CountryForm(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['name_%s' % code] = forms.CharField(label='Название', required=required) - self.fields['description_%s' % code] = forms.CharField(label='Описание', required=False, widget=CKEditorWidget) - self.fields['transport_%s' % code] = forms.CharField(label='Транспорт', required=False, widget=CKEditorWidget) + self.fields['name_%s' % code] = forms.CharField(label=_(u'Название'), required=required) + self.fields['description_%s' % code] = forms.CharField(label=_(u'Описание'), required=False, widget=CKEditorWidget) + self.fields['transport_%s' % code] = forms.CharField(label=_(u'Транспорт'), required=False, widget=CKEditorWidget) #vis inf - self.fields['rules_%s' % code] = forms.CharField(label='Правила въезда', required=False, widget=CKEditorWidget()) - self.fields['documents_%s' % code] = forms.CharField(label='Документы', required=False, widget=CKEditorWidget()) - self.fields['consulate_%s' % code] = forms.CharField(label='Консульство', required=False, widget=CKEditorWidget()) + self.fields['rules_%s' % code] = forms.CharField(label=_(u'Правила въезда'), required=False, widget=CKEditorWidget()) + self.fields['documents_%s' % code] = forms.CharField(label=_(u'Документы'), required=False, widget=CKEditorWidget()) + self.fields['consulate_%s' % code] = forms.CharField(label=_(u'Консульство'), required=False, widget=CKEditorWidget()) #meta data - self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=False, max_length=255, + self.fields['title_%s' % code] = forms.CharField(label=_(u'Тайтл'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=False, max_length=255, + self.fields['keywords_%s' % code] = forms.CharField(label=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) - self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, + self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) # check if exists cities connected with country countries = City.objects.language().filter(country = country_id).order_by('name') countries_list = [(item.id, item.name) for item in countries] if country_id == None or len(countries)==0: - self.fields['capital'] = forms.ChoiceField(label='Столица',choices=((None,'Нет городов в стране'),), required=False, + self.fields['capital'] = forms.ChoiceField(label=_(u'Столица'),choices=((None,_(u'Нет городов в стране')),), required=False, widget=forms.Select(attrs={'disabled' : True})) - self.fields['big_cities'] = forms.MultipleChoiceField(label='Большие города',choices=((None,'Нет городов в стране'),), required=False, + self.fields['big_cities'] = forms.MultipleChoiceField(label=_(u'Большие города'),choices=((None,_(u'Нет городов в стране')),), required=False, widget=forms.Select(attrs={'disabled' : True})) else: - self.fields['capital'] = forms.ChoiceField(label='Столица', choices=countries_list, + self.fields['capital'] = forms.ChoiceField(label=_(u'Столица'), choices=countries_list, required=False) - self.fields['big_cities'] = forms.MultipleChoiceField(label='Большие города', choices=countries_list, + self.fields['big_cities'] = forms.MultipleChoiceField(label=_(u'Большие города'), choices=countries_list, required=False) def save(self, id=None): @@ -181,7 +183,7 @@ class CountryForm(forms.Form): if phone_code.isdigit(): return phone_code else: - raise ValidationError('Введите правильный код страны') + raise ValidationError(_(u'Введите правильный код страны')) def clean_population(self): @@ -195,7 +197,7 @@ class CountryForm(forms.Form): elif population.isdigit() and population > 0: return int(population) else: - raise ValidationError('Введите правильное население') + raise ValidationError(_(u'Введите правильное население')) def clean_teritory(self): """ @@ -215,11 +217,11 @@ class CountryForm(forms.Form): class CountryDeleteForm(forms.ModelForm): url = forms.CharField(widget=forms.HiddenInput()) - + class Meta: model = Country fields = ('url',) class CountryFilterForm(AdminFilterForm): - model = Country \ No newline at end of file + model = Country diff --git a/country/models.py b/country/models.py index eb086ae7..eeada101 100644 --- a/country/models.py +++ b/country/models.py @@ -90,7 +90,7 @@ class Country(TranslatableModel): # inflect name for russian language. example- в Росии inflect = models.CharField(verbose_name=_(u'Склонение'), max_length=255, blank=True) area = models.ForeignKey(Area, verbose_name=_(u'Географическая зона')) - logo = models.ImageField(verbose_name='Logo', upload_to='country/logo/', blank=True, max_length=255) + logo = models.ImageField(verbose_name=_(u'Logo'), upload_to='country/logo/', blank=True, max_length=255) big_cities = models.ManyToManyField(City, verbose_name=_(u'Большые города'), blank=True, null=True, related_name='cities') capital = models.ForeignKey(City, verbose_name=_(u'Столица'), blank=True, null=True, on_delete=models.PROTECT, related_name='capital') language = models.ManyToManyField(Language, blank=True, null=True) @@ -173,4 +173,4 @@ class Country(TranslatableModel): pre_save.connect(pre_save_handler, sender=Country) -post_save.connect(post_save_handler, sender=Country) \ No newline at end of file +post_save.connect(post_save_handler, sender=Country) diff --git a/django_messages/admin.py b/django_messages/admin.py index 91d004a1..d0f7bd50 100644 --- a/django_messages/admin.py +++ b/django_messages/admin.py @@ -11,7 +11,7 @@ if "notification" in settings.INSTALLED_APPS: from notification import models as notification else: notification = None - + from django_messages.models import Message class MessageAdminForm(forms.ModelForm): @@ -19,7 +19,7 @@ class MessageAdminForm(forms.ModelForm): Custom AdminForm to enable messages to groups and all users. """ group = forms.ChoiceField(label=_('group'), required=False, - help_text=_('Creates the message optionally for all users or a group of users.')) + help_text=_(_(u'Creates the message optionally for all users or a group of users.'))) def __init__(self, *args, **kwargs): super(MessageAdminForm, self).__init__(*args, **kwargs) @@ -75,7 +75,7 @@ class MessageAdmin(admin.ModelAdmin): the message is effectively resent to those users. """ obj.save() - + if notification: # Getting the appropriate notice labels for the sender and recipients. if obj.parent_msg is None: @@ -84,7 +84,7 @@ class MessageAdmin(admin.ModelAdmin): else: sender_label = 'messages_replied' recipients_label = 'messages_reply_received' - + # Notification for the sender. notification.send([obj.sender], sender_label, {'message': obj,}) @@ -108,5 +108,5 @@ class MessageAdmin(admin.ModelAdmin): if notification: # Notification for the recipient. notification.send([user], recipients_label, {'message' : obj,}) - + admin.site.register(Message, MessageAdmin) diff --git a/emencia/django/newsletter/admin_forms.py b/emencia/django/newsletter/admin_forms.py index f70ed361..ce428c9a 100644 --- a/emencia/django/newsletter/admin_forms.py +++ b/emencia/django/newsletter/admin_forms.py @@ -9,7 +9,7 @@ from country.models import Country, Area class ContactSettingsForm(forms.ModelForm): - city = forms.CharField(label=u'Город', widget=forms.HiddenInput() ,required=False) + city = forms.CharField(label=_(u'Город'), widget=forms.HiddenInput() ,required=False) periodic = forms.ChoiceField(choices=ContactSettings.PERIODIC_CHOICES, label=_(u'Периодичность отправки')) first_name = forms.CharField(label=_('first name')) @@ -65,8 +65,8 @@ import xlrd from theme.models import Theme class MailingListForm(forms.ModelForm): - excel_file = forms.FileField(label='Импортировать подписчиков', required=False) - theme_for_filter = forms.MultipleChoiceField(label=u'Тематики', required=False, + excel_file = forms.FileField(label=_(u'Импортировать подписчиков'), required=False) + theme_for_filter = forms.MultipleChoiceField(label=_(u'Тематики'), required=False, choices=[(item.id, item.name) for item in Theme.objects.language().all()]) class Meta: @@ -92,7 +92,7 @@ class MailingListForm(forms.ModelForm): class NewsletterForm(forms.ModelForm): - test_contacts = forms.ModelMultipleChoiceField(label=u'Тестовые контакты', required=False, + test_contacts = forms.ModelMultipleChoiceField(label=_(u'Тестовые контакты'), required=False, queryset=Contact.objects.filter(tester=True)) content = forms.CharField(label=_('content'), widget=CKEditorWidget(config_name='newsletters')) @@ -105,4 +105,4 @@ class NewsletterForm(forms.ModelForm): class AttachmentForm(forms.ModelForm): class Meta: model = Attachment - fields = ('title', 'file_attachment') \ No newline at end of file + fields = ('title', 'file_attachment') diff --git a/emencia/django/newsletter/forms.py b/emencia/django/newsletter/forms.py index 1aba6f53..b992a5af 100644 --- a/emencia/django/newsletter/forms.py +++ b/emencia/django/newsletter/forms.py @@ -129,11 +129,11 @@ class ContactFilterForm(forms.Form): label="Список рассылки", required=False ) - created_from = forms.CharField(max_length=255, label="Создан с", required=False) - created_to = forms.CharField(max_length=255, label="Создан по", required=False) - not_active = forms.BooleanField(label="Не подтверждена подписка", required=False) - not_valid = forms.BooleanField(label="Неалидный Email", required=False) - not_subscriber = forms.BooleanField(label="Отписался", required=False) + created_from = forms.CharField(max_length=255, label=_(u"Создан с"), required=False) + created_to = forms.CharField(max_length=255, label=_(u"Создан по"), required=False) + not_active = forms.BooleanField(label=_(u"Не подтверждена подписка"), required=False) + not_valid = forms.BooleanField(label=_(u"Неалидный Email"), required=False) + not_subscriber = forms.BooleanField(label=_(u"Отписался"), required=False) def filter(self): title = 'contact list ' @@ -181,14 +181,14 @@ class ContactFilterForm(forms.Form): import xlrd COUNTRY_CHOICES = [(c.id, c.name) for c in list(set(Country.objects.language('ru').all()))] -COUNTRY_CHOICES.insert(0, ('', 'Страна')) +COUNTRY_CHOICES.insert(0, ('', _(u'Страна'))) class ContactImportForm(forms.Form): - excel_file = forms.FileField(label='Выберите файл') - activated = forms.BooleanField(label="Активные", required=False) - is_tester = forms.BooleanField(label="Тестовые", required=False) - country = forms.ChoiceField(label="Страна", choices=COUNTRY_CHOICES, required=False) + excel_file = forms.FileField(label=_(u'Выберите файл')) + activated = forms.BooleanField(label=_(u"Активные"), required=False) + is_tester = forms.BooleanField(label=_(u"Тестовые"), required=False) + country = forms.ChoiceField(label=_(u"Страна"), choices=COUNTRY_CHOICES, required=False) def save(self): data = self.cleaned_data @@ -375,7 +375,7 @@ class PopupCountFilter(forms.Form): class MailingStatusFilter(forms.Form): - status = forms.ChoiceField(choices=[('', u'Не выбрано')] + [(item[0], item[1]) for item in ContactMailingStatus.STATUS_CHOICES], + status = forms.ChoiceField(choices=[('', _(u'Не выбрано'))] + [(item[0], item[1]) for item in ContactMailingStatus.STATUS_CHOICES], required=False) email = forms.CharField(required=False, widget=forms.TextInput(attrs={'placeholder': 'Email'})) @@ -387,4 +387,4 @@ class MailingStatusFilter(forms.Form): qs = qs.filter(status=status) if email: qs = qs.filter(contact__email=email) - return qs \ No newline at end of file + return qs diff --git a/emencia/django/newsletter/templates/newsletter/announce_template.html b/emencia/django/newsletter/templates/newsletter/announce_template.html index 992ab4d9..c65b56d4 100644 --- a/emencia/django/newsletter/templates/newsletter/announce_template.html +++ b/emencia/django/newsletter/templates/newsletter/announce_template.html @@ -1,3 +1,4 @@ +{% load i18n %}
| @@ -77,7 +78,7 @@ {% if news %} |
| Новости событий | +{% trans "Новости событий" %} |
| @@ -109,7 +110,7 @@ |
| Аналитика для профессионалов | +{% trans "Аналитика для профессионалов" %} |
| @@ -162,9 +163,9 @@ |
diff --git a/emencia/django/newsletter/templates/newsletter/base.html b/emencia/django/newsletter/templates/newsletter/base.html index ffe4a2b3..94691456 100644 --- a/emencia/django/newsletter/templates/newsletter/base.html +++ b/emencia/django/newsletter/templates/newsletter/base.html @@ -1,3 +1,5 @@ +{% load i18n %} +
@@ -5,10 +7,10 @@ -
+
diff --git a/emencia/django/newsletter/templates/newsletter/mailing_list_unsubscribe.html b/emencia/django/newsletter/templates/newsletter/mailing_list_unsubscribe.html index 3605bb72..402cd0fd 100644 --- a/emencia/django/newsletter/templates/newsletter/mailing_list_unsubscribe.html +++ b/emencia/django/newsletter/templates/newsletter/mailing_list_unsubscribe.html @@ -1,17 +1,19 @@ {% extends 'client/blank.html' %} +{% load i18n %} -{% block title %}Отписаться{% endblock %} + +{% block title %}{% trans "Отписаться" %}{% endblock %} {% block content %}
| Чтобы отписаться от этой рассылки, перейдите по ссылке. + | {% trans "Чтобы отписаться от этой рассылки, перейдите" %} {% trans "по ссылке" %}. | © 2008 — 2015 Expomap.ru |