# -*- coding: utf-8 -*- from django import forms from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError #models from models import Exposition, TimeTable, AUDIENCE1, CURRENCY from country.models import Country from theme.models import Theme from organiser.models import Organiser from accounts.models import User from company.models import Company from city.models import City from service.models import Service from place_exposition.models import PlaceExposition #functions from functions.translate import populate_all, fill_trans_fields_all from functions.form_check import is_positive_integer from functions.files import check_tmp_files from functions.form_check import translit_with_separator class ExpositionCreateForm(forms.Form): """ Create Exposition form for creating exposition __init__ uses for dynamic creates fields save function saves data in Exposition object. If it doesnt exist create new object """ PERIODIC = ((0, 'Не выбрано'), (1.0, 'Ежегодно'), (2.0, '2 раза в год'), (3.0, '3 раза в год'), (4.0, '4 раза в год'), (5.0, '5 раз в год'), (0.5, 'Раз в 2 года'),(0.33, 'Раз в 3 года'),(0.25, 'Раз в 4 года')) public = [(item1, item2) for item1, item2 in AUDIENCE1] currencies = [(item, item) for item in CURRENCY] data_begin = forms.DateField(label='Дата начала') data_end = forms.DateField(label='Дата окночания') country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None) theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) place = forms.ModelChoiceField(label='Место проведения', queryset=PlaceExposition.objects.all(), empty_label='', required=False) #creates select input with empty choices cause it will be filled with ajax city = forms.ChoiceField(label='Город', choices=[('','')]) tag = forms.MultipleChoiceField(label='Теги', required=False) periodic = forms.ChoiceField(label='Периодичность', choices=PERIODIC, required=False) audience = forms.ChoiceField(label='Аудитория', choices=public, initial='', required=False) web_page = forms.CharField(label='Веб страница', required=False) foundation_year = forms.CharField(label='Год основания', required=False) min_area = forms.CharField(label='Минимальная плошадь', required=False) # currency = forms.ChoiceField(label='Валюта', choices=currencies, required=False) tax = forms.BooleanField(label='Налог включен', initial=True, required=False) min_closed_area = forms.CharField(label='Минимальная цена закрытой НЕ оборудованной площади', required=False) max_closed_area = forms.CharField(label='Максимальная цена закрытой НЕ оборудованной площади', required=False) min_closed_equipped_area = forms.CharField(label='Минимальная цена закрытой оборудованной площади', required=False) max_closed_equipped_area = forms.CharField(label='Максимальная цена закрытой оборудованной площади', required=False) min_open_area = forms.CharField(label='Минимальная цена открытой площади', required=False) max_open_area = forms.CharField(label='Максимальная цена открытой площади', required=False) registration_payment = forms.CharField(label='Регистрационны взнос', required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ create dynamical translated fields fields """ super(ExpositionCreateForm, self).__init__(*args, **kwargs) #creates translated forms 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): # 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='Краткое описание', required=False, widget=CKEditorWidget) self.fields['description_%s' % code] = forms.CharField(label='Описание', required=False, widget=CKEditorWidget) self.fields['time_%s' % code] = forms.CharField(label='Время работы', required=False, widget=CKEditorWidget) self.fields['products_%s' % code] = forms.CharField(label='Экспонируемые продукты', required=False, widget=CKEditorWidget) #meta data self.fields['title_%s' % code] = forms.CharField(label='Тайтл', required=required, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['keywords_%s' % code] = forms.CharField(label='Дескрипшен', required=required, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['descriptions_%s' % code] = forms.CharField(label='Кейвордс', required=required, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) #creates select inputs ind fill it #!service has bitfield. uncomment when country data will be filled #services = [(item.id, item.name) for item in Service.objects.all()] #self.fields['service'] = forms.MultipleChoiceField(label='Услуги', choices=services, required=False) def save(self, id=None): """ change Exposition model object with id = id N/A add new Exposition model object usage: form.save(obj) - if change exposition form.save() - if add exposition """ data = self.cleaned_data if not id: exposition = Exposition() else: exposition = Exposition.objects.get(id=id) exposition.theme.clear() exposition.tag.clear() #simple fields exposition.url = translit_with_separator(data['name_ru']) exposition.data_begin = data['data_begin'] exposition.data_end = data['data_end'] exposition.periodic = data['periodic'] exposition.audience = data['audience'] exposition.web_page= data['web_page'] exposition.foundation_year = data['foundation_year'] exposition.min_area = data['min_area'] # exposition.currency = data['currency'] exposition.tax = data['tax'] exposition.min_closed_area = data['min_closed_area'] exposition.max_closed_area = data['max_closed_area'] exposition.min_closed_equipped_area = data['min_closed_equipped_area'] exposition.max_closed_equipped_area = data['max_closed_equipped_area'] exposition.min_open_area = data['min_open_area'] exposition.max_open_area = data['max_open_area'] exposition.registration_payment = data['registration_payment'] if data.get('country'): exposition.country = Country.objects.get(id=data['country'].id)#.id cause select uses queryset if data.get('city'): exposition.city = City.objects.get(id=data['city']) if data.get('place'): exposition.place = PlaceExposition.objects.get(id=data['place'].id)#.id cause select uses queryset # uses because in the next loop data will be overwritten exposition.save() #fill manytomany fields for item in data['theme']: exposition.theme.add(item.id)#.id cause select uses queryset for item in data['tag']: exposition.tag.add(item) # uses because in the next loop data will be overwritten exposition.save() #will be saved populated fields zero_fields = {} #fills all translated fields with data #if saves new object, will fill city object. otherwise existing object of City model fill_trans_fields_all(Exposition, exposition, data, id, zero_fields) #autopopulate #populate empty fields and fields which was already populated exposition_id = getattr(exposition, 'id') populate_all(Exposition, data, exposition_id, zero_fields) #save files check_tmp_files(exposition, data['key']) def clean_name_ru(self): """ check name which must be unique because it generate slug field """ cleaned_data = super(ExpositionCreateForm, self).clean() name_ru = cleaned_data.get('name_ru') try: exposition = Exposition.objects.get(url=translit_with_separator(name_ru)) if (exposition.url == translit_with_separator(name_ru)): return name_ru except: return name_ru raise ValidationError('Выставка с таким названием уже существует') def clean_web_page(self): """ checking web_page """ cleaned_data = super(ExpositionCreateForm, self).clean() web_page = cleaned_data.get('web_page') if not web_page: return web_page import socket try: socket.getaddrinfo(web_page, 80) return web_page except: raise forms.ValidationError('Введите правильный адрес страници') def clean_foundation_year(self): """ checking foundation_year """ cleaned_data = super(ExpositionCreateForm, self).clean() foundation_year = cleaned_data.get('foundation_year').strip() return is_positive_integer(foundation_year) def clean_min_area(self): """ checking min_area """ cleaned_data = super(ExpositionCreateForm, self).clean() min_area = cleaned_data.get('min_area').strip() return is_positive_integer(min_area) def clean_min_closed_area(self): """ checking min_closed_area """ cleaned_data = super(ExpositionCreateForm, self).clean() min_closed_area = cleaned_data.get('min_closed_area').strip() return is_positive_integer(min_closed_area) # def clean_max_closed_area(self): """ checking max_closed_area """ cleaned_data = super(ExpositionCreateForm, self).clean() max_closed_area = cleaned_data.get('max_closed_area').strip() return is_positive_integer(max_closed_area) def clean_min_closed_equipped_area(self): """ checking min_closed_equipped_area """ cleaned_data = super(ExpositionCreateForm, self).clean() min_closed_equipped_area = cleaned_data.get('min_closed_equipped_area').strip() return is_positive_integer(min_closed_equipped_area) def clean_max_closed_equipped_area(self): """ checking max_closed_equipped_area """ cleaned_data = super(ExpositionCreateForm, self).clean() max_closed_equipped_area = cleaned_data.get('max_closed_equipped_area').strip() return is_positive_integer(max_closed_equipped_area) def clean_min_open_area(self): """ checking min_open_area """ cleaned_data = super(ExpositionCreateForm, self).clean() min_open_area = cleaned_data.get('min_open_area').strip() return is_positive_integer(min_open_area) def clean_max_open_area(self): """ checking max_open_area """ cleaned_data = super(ExpositionCreateForm, self).clean() max_open_area = cleaned_data.get('max_open_area').strip() return is_positive_integer(max_open_area) def clean_registration_payment(self): """ checking registration_payment """ cleaned_data = super(ExpositionCreateForm, self).clean() registration_payment = cleaned_data.get('registration_payment').strip() return is_positive_integer(registration_payment) class ExpositionChangeForm(ExpositionCreateForm): """ add some fields to ExpositionCreateForm """ 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) class TimeTableForm(forms.Form): begin = forms.DateTimeField(label='Время начала', widget=forms.TextInput(attrs={'style':'width: 150px'})) end = forms.DateTimeField(label='Время окончания', widget=forms.TextInput(attrs={'style':'width: 150px'})) def __init__(self, *args, **kwargs): """ create dynamical translated fields fields and fills select fields """ super(TimeTableForm, self).__init__(*args, **kwargs) #creates translated forms 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): # 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) def save(self, id=None): pass