# -*- coding: utf-8 -*- from django import forms from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError from django.forms.util import ErrorList #models from models import Country, City from directories.models import Language, Currency, Iata #functions from functions.translate import fill_with_signal from functions.files import check_tmp_files from functions.form_check import is_positive_integer, translit_with_separator tz = [ (99, ''), (-12.0, '(GMT -12:00) Eniwetok, Kwajalein'), (-11.0,'(GMT -11:00) Midway Island, Samoa'), (-10.0,'(GMT -10:00) Hawaii'), (-9.0,'(GMT -9:00) Alaska'), (-8.0,'(GMT -8:00) Pacific Time'),(-7.0,'(GMT -7:00) Mountain Time'), (-6.0,'(GMT -6:00) Central Time'),(-5.0,'(GMT -5:00) Eastern Time'), (-4.0,'(GMT -4:00) Atlantic Time'),(-3.5,'(GMT -3:30) Newfoundland'), (-3.0,'(GMT -3:00) Brazil, Buenos Aires'), (-2.0,'(GMT -2:00) Mid-Atlantic'), (-1.0,'(GMT -1:00 hour) Azores, Cape Verde Islands'), (0,'(GMT) Western Europe Time, London, Lisbon, Casablanca'), (1.0,'(GMT +1:00 hour) Brussels, Copenhagen, Madrid, Paris'), (2.0,'(GMT +2:00) Kaliningrad, Kiev, South Africa'), (3.0,'(GMT +3:00) Moscow, St. Petersburg, Baghdad'), (3.5,'(GMT +3:30) Tehran'), (4.0,'(GMT +4:00) Abu Dhabi, Muscat, Baku, Tbilisi'), (4.5,'(GMT +4:30) Kabul'), (5.0,'(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent'), (5.5,'(GMT +5:00) Ekaterinburg, Islamabad, Karachi, Tashkent'), (5.75,'(GMT +5:45) Kathmandu'),(6.0,'(GMT +6:00) Almaty, Dhaka, Colombo'), (7.0,'(GMT +7:00) Bangkok, Hanoi, Jakarta'), (8.0,'(GMT +8:00) Beijing, Perth, Singapore, Hong Kong'), (9.0,'(GMT +9:00) Tokyo, Seoul, Osaka, Sapporo, Yakutsk'), (9.5,'(GMT +9:30) Adelaide, Darwin'), (10.0,'(GMT +10:00) Eastern Australia, Guam, Vladivostok'), (11.0,'(GMT +11:00) Magadan, Solomon Islands, New Caledonia'), (12.0,'(GMT +12:00) Auckland, Wellington, Fiji, Kamchatka')] class CountryForm(forms.Form): """ Create Country form __init__ uses for dynamic creates fields 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) # population = forms.CharField(label='Население(млн)', required=False, widget=forms.TextInput(attrs={'placeholder':'Население(млн)'})) 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':'Срок выдачи'})) region = forms.ChoiceField(label='Регион', choices=((item, item) for item in Country.REGIONS)) #services = forms.MultipleChoiceField(label='Сервисы', required=False, choices=); #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) # country_id = forms.CharField(required=False, widget=forms.HiddenInput) def __init__(self, *args, **kwargs ): """ creates dynamical translated fields and fills select fields Also check if exist cities connected to this Country and create field based on this information """ country_id = kwargs.get('country_id') if 'country_id' in kwargs: del kwargs['country_id'] super(CountryForm, 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 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['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) #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()) #meta data self.fields['title_%s' % code] = forms.CharField(label='Тайтл', 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, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) # check if exists cities connected with country countries = City.objects.filter(country = country_id) 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, widget=forms.Select(attrs={'disabled' : True})) self.fields['big_cities'] = forms.MultipleChoiceField(label='Большые города',choices=((None,'Нет городов в стране'),), required=False, widget=forms.Select(attrs={'disabled' : True})) else: self.fields['capital'] = forms.ChoiceField(label='Столица', choices=countries_list, required=False) self.fields['big_cities'] = forms.MultipleChoiceField(label='Большые города', choices=countries_list, required=False) def save(self, id=None): """ change Country model object with id = id N/A add new Country model object usage: form.save(obj) - if change country form.save() - if add country """ data = self.cleaned_data #create new Country object or get exists if not id: country = Country() else: country = Country.objects.get(id=id) country.big_cities.clear() country.language.clear() country.currency.clear() country.url = translit_with_separator(data['name_ru'].strip()).lower() country.population = data['population'] country.teritory = data['teritory'] country.timezone = data['timezone'] country.phone_code = data['phone_code'] country.time_delivery = data['time_delivery'] country.region = data['region'] if data.get('capital'): country.capital = City.objects.get(id=data['capital']) # fill translated fields and save object fill_with_signal(Country, country, data) # fill manytomany fields for item in data['language']: country.language.add(item.id)#.id cause select uses queryset for item in data['big_cities']: country.big_cities.add(item) for item in data['currency']: country.currency.add(item.id)#.id cause select uses queryset country.save() # save files check_tmp_files(country, data['key']) def clean(self): data = self.cleaned_data id = data.get('country_id') name_ru = data.get('name_ru') country = Country.objects.filter(url=translit_with_separator(name_ru)) if country and str(country[0].id) != id: msg = 'Страна с таким названием уже существует' self._errors['name_ru'] = ErrorList([msg]) del data['name_ru'] return data def clean_phone_code(self): """ phone code checking """ cleaned_data = super(CountryForm, self).clean() phone_code = cleaned_data.get('phone_code') if not phone_code: return deduct = ('-','(',')','.',' ') for elem in deduct: phone_code = phone_code.replace(elem, '') if phone_code.isdigit(): return phone_code else: raise ValidationError('Введите правильный код страны') def clean_population(self): """ checking population """ cleaned_data = super(CountryForm, self).clean() population = cleaned_data.get('population').strip() if not population: return elif population.isdigit() and population > 0: return int(population) else: raise ValidationError('Введите правильное население') def clean_teritory(self): """ checking teritory """ cleaned_data = super(CountryForm, self).clean() teritory = cleaned_data.get('teritory').strip() return is_positive_integer(teritory) def clean_time_delivery(self): """ checking time_delivery """ cleaned_data = super(CountryForm, self).clean() time_delivery = cleaned_data.get('time_delivery').strip() return is_positive_integer(time_delivery) class CountryDeleteForm(forms.ModelForm): url = forms.CharField(widget=forms.HiddenInput()) class Meta: model = Country fields = ('url',)