# -*- coding: utf-8 -*- from django import forms 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, Speaker from country.models import Country from city.models import City from theme.models import Theme, Tag from organiser.models import Organiser from accounts.models import User from company.models import Company from service.models import Service from place_conference.models import PlaceConference #functions from functions.translate import populate_all, fill_trans_fields_all, fill_with_signal from functions.form_check import is_positive_integer from functions.files import check_tmp_files from functions.form_check import translit_with_separator from functions.admin_forms import AdminFilterForm, EventsAdminFilterFormMixin places = [(item.id, item.name) for item in PlaceConference.objects.language().all()] places.insert(0,('', 'Не выбрано')) class ConferenceCreateForm(forms.Form): """ Create Conference form for creating conference __init__ uses for dynamic creates fields 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 лет'))) 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=_(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.language().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, choices=places) 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_once = forms.CharField(label=_(u'Проводится в n-й раз'), required=False) periodic = forms.ChoiceField(label=_(u'Периодичность'), choices=PERIODIC, required=False) programm_link = forms.URLField(label=_(u'Программа (урл)'), 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) members_fc = forms.IntegerField(label=_(u'Ожидаемое количество участников'), required=False) visitors = forms.CharField(label=_(u'Посетители'), required=False) discount = forms.CharField(label=_(u'Cкидка(%)'), 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()) speakers = forms.ModelMultipleChoiceField(label=_(u'Спикеры'), queryset=Speaker.objects.all(), required=False) conference_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ create dynamical translated fields fields """ super(ConferenceCreateForm, 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=_(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=_(u'Описание'), required=False, widget=CKEditorWidget) self.fields['time_%s' % code] = forms.CharField(label=_(u'Время работы'), required=False, widget=CKEditorWidget) self.fields['main_themes_%s' % code] = forms.CharField(label=_(u'Основные темы'), required=False, widget=CKEditorWidget) self.fields['discount_description_%s' % code] = forms.CharField(label=_(u'Описание скидки'), required=False, widget=CKEditorWidget) #meta data 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=_(u'Дескрипшен'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['descriptions_%s' % code] = forms.CharField(label=_(u'Кейвордс'), required=False, max_length=255, widget=forms.TextInput(attrs={'style':'width: 550px'})) def save(self, obj=None): """ changes Conference model object with id = id N/A add new Conference model object usage: form.save(obj) - if change conference form.save() - if add conference """ data = self.cleaned_data #create new conference object or get exists if not obj: conference = Conference() else: conference = obj conference.theme.clear() if data.get('tag'): conference.tag.clear() #simple fields if not getattr(conference, 'url'): conference.url = translit_with_separator(data['name_ru'].strip()).lower() if data.get('logo'): conference.logo = data['logo'] conference.org = data['org'] conference.data_begin = data['data_begin'] conference.data_end = data['data_end'] conference.link = data['link'] conference.web_page= data['web_page'] conference.foundation_year = data['foundation_year'] conference.periodic_once = data['periodic_once'] conference.programm_link = data['programm_link'] conference.members = data['members'] conference.members_fc = data['members_fc'] conference.visitors = data['visitors'] # conference.currency = data['currency'] conference.tax = data['tax'] conference.min_price = data['min_price'] conference.max_price = data['max_price'] conference.discount = data['discount'] conference.expohit = data['expohit'] conference.canceled = data['canceled'] conference.moved = data['moved'] conference.periodic = data['periodic'] conference.place_alt = data['place_alt'] # generates bitfield flag = 0 if data['quality_label']: flag = reduce(lambda x,y: x|y, (getattr(Conference.quality_label, item) for item in data['quality_label'])) conference.quality_label = flag audience = 0 if data['audience']: audience = reduce(lambda x,y: x|y, (getattr(Conference.audience, item) for item in data['audience'])) conference.audience = audience if data.get('country'): conference.country = Country.objects.get(id=data['country'])#.id cause select uses queryset if data.get('city'): conference.city = City.objects.get(id=data['city']) if data.get('place'): conference.place = PlaceConference.objects.get(id=data['place']) else: conference.place = None # fill translated fields and save object fill_with_signal(Conference, conference, data) conference.theme.add(*data['theme']) conference.tag.add(*Tag.objects.filter(id__in=data['tag'])) conference.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', []))) conference.save() return conference """ def clean(self): id = self.cleaned_data.get('conference_id') name_ru = self.cleaned_data.get('name_ru') conference = Conference.objects.filter(url=translit_with_separator(name_ru)) if conference and str(conference[0].id) != id: msg = 'Конференция с таким названием уже существует' self._errors['name_ru'] = ErrorList([msg]) del self.cleaned_data['name_ru'] return self.cleaned_data """ def clean_tag(self): tags = self.cleaned_data.get('tag') if tags: res = [] for id in tags.split(','): try: res.append(int(id)) except: continue return res else: return [] def clean_web_page(self): """ checking web_page """ cleaned_data = super(ConferenceCreateForm, self).clean() web_page = cleaned_data.get('web_page') if not web_page: return '' validate = URLValidator() try: validate(web_page) except(forms.ValidationError),e: raise forms.ValidationError(e.messages[0]) return web_page def clean_link(self): """ checking link """ cleaned_data = super(ConferenceCreateForm, self).clean() link = cleaned_data.get('link') if not link: return '' validate = URLValidator() try: validate(link) except(forms.ValidationError),e: raise forms.ValidationError(e.messages[0]) return link def clean_foundation_year(self): """ checking foundation_year """ cleaned_data = super(ConferenceCreateForm, self).clean() foundation_year = cleaned_data.get('foundation_year').strip() return is_positive_integer(foundation_year) def clean_visitors(self): """ checking visitors """ cleaned_data = super(ConferenceCreateForm, self).clean() visitors = cleaned_data.get('visitors').strip() return is_positive_integer(visitors) def clean_members(self): """ checking members """ cleaned_data = super(ConferenceCreateForm, self).clean() members = cleaned_data.get('members').strip() return is_positive_integer(members) def clean_min_price(self): """ checking min_price """ cleaned_data = super(ConferenceCreateForm, self).clean() min_price = cleaned_data.get('min_price').strip() return is_positive_integer(min_price) def clean_max_price(self): """ checking max_price """ cleaned_data = super(ConferenceCreateForm, self).clean() max_price = cleaned_data.get('max_price').strip() return is_positive_integer(max_price) def clean_discount(self): """ checking discount """ cleaned_data = super(ConferenceCreateForm, self).clean() discount = cleaned_data.get('discount').strip() return is_positive_integer(discount) class ConferenceChangeForm(ConferenceCreateForm): """ add some fields to ConferenceCreateForm """ 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): url = forms.CharField(widget=forms.HiddenInput) class Meta: model = Conference fields = ('url',) class StatisticForm(forms.ModelForm): year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'})) visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) class Meta: model = Statistic exclude = ('conference') def clean_year(self): cleaned_data = super(StatisticForm, self).clean() year = cleaned_data.get('year').strip() return is_positive_integer(year) def clean_members(self): cleaned_data = super(StatisticForm, self).clean() members = cleaned_data.get('members').strip() return is_positive_integer(members) def clean_visitors(self): cleaned_data = super(StatisticForm, self).clean() visitors = cleaned_data.get('visitors').strip() return is_positive_integer(visitors) class TimeTableForm(forms.Form): """ Create TimeTable form day field must save automatically """ begin = forms.DateTimeField(label=_(u'Время начала')) end = forms.DateTimeField(label=_(u'Время окончания')) 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 class ConferenceFilterForm(EventsAdminFilterFormMixin, AdminFilterForm): created = forms.DateField(required=False, label=_(u'Дата создания')) model = Conference def filter(self): qs = super(ConferenceFilterForm, self).filter() data = self.cleaned_data created = data['created'] if created: qs = qs.filter(created__startswith=created) return qs