You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

152 lines
6.7 KiB

# -*- 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