# -*- coding: utf-8 -*- from django import forms from django.conf import settings from django.contrib.contenttypes.models import ContentType from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError from models import News, TYPES from theme.models import Theme from organiser.models import Organiser from django.db.models.loading import get_model #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 NewsForm(forms.Form): """ Create News form In __init__ function creates dynamical fields save function saves data in News object. If it doesnt exist create new object """ date = forms.DateField(label='Дата') type = forms.ChoiceField(label='Тип новости', choices=[(item, item) for item in TYPES]) paid = forms.BooleanField(label='Платная', required=False) #relations theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all()) #creates select input with empty choices cause it will be filled with ajax tag = forms.MultipleChoiceField(label='Теги', required=False) organiser = forms.ModelChoiceField(label='Организатор', queryset=Organiser.objects.all(), empty_label='') # event = forms.ChoiceField(label='Тип события', choices=[(None, ''), ('conference.Conference', 'Конференция'), ('exposition.Exposition', 'Выставка')], required=False) event_id = forms.ChoiceField(label='Событие', choices=[(None,'')], 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(NewsForm, 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['main_title_%s' % code] = forms.CharField(label='Заголовок', required=required, widget=forms.TextInput(attrs={'style':'width: 550px'})) self.fields['preview_%s' % code] = forms.CharField(label='Превью', required=required, widget=CKEditorWidget) self.fields['description_%s' % code] = forms.CharField(label='Описание', required=required, 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'})) def save(self, id=None): """ change news object with id = id N/A add new News object usage: form.save(id) - if change company form.save() - if add company """ data = self.cleaned_data #create new Company object or get exists if not id: news = News() else: news = News.objects.get(id=id) news.theme.clear() news.tag.clear() #save relation if its filled obj = get_model(data['event'].split('.')[0],data['event'].split('.')[1]).objects.get(id=data['event_id']) news.content_type = ContentType.objects.get_for_model(obj)# news.object_id = data['event_id'] #simple fields news.url = translit_with_separator(data['main_title_ru']) news.date = data['date'] news.type = data['type'] news.paid = data['paid'] if data.get('organiser'): news.organiser = data['organiser'] # uses because in the next loop data will be overwritten news.save() #fill manytomany fields for item in data['theme']: news.theme.add(item.id)#.id cause select uses queryset for item in data['tag']: news.tag.add(item) # uses because in the next loop data will be overwritten news.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(News, news, data, id, zero_fields) #autopopulate #populate empty fields and fields which was already populated news_id = getattr(news, 'id') populate_all(News, data, news_id, zero_fields) #save files check_tmp_files(news, data['key']) def clean_main_title_ru(self): """ check name which must be unique because it generate slug field """ cleaned_data = super(NewsForm, self).clean() main_title_ru = cleaned_data.get('main_title_ru') try: News.objects.get(url=translit_with_separator(main_title_ru)) except: return main_title_ru raise ValidationError('Новость с таким названием уже существует') def clean_event_id(self): """ check event_id which must be filled only if event field filled """ cleaned_data = super(NewsForm, self).clean() event = cleaned_data.get('event') event_id = cleaned_data.get('event_id') if not event_id and event: raise ValidationError('Вы должны выбрать тип события') else: return event_id class NewsChangeForm(NewsForm): """ cancel checking url """ def clean_main_title_ru(self): cleaned_data = super(NewsForm, self).clean() main_title_ru = cleaned_data.get('main_title_ru') return main_title_ru