diff --git a/accounts/models.py b/accounts/models.py index 07f0b386..02317219 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -6,7 +6,6 @@ from django.core.mail import send_mail from django.utils import timezone from django.db.models.signals import post_save #custom functions -from functions.custom_fields import LocationField from functions.form_check import translit_with_separator """ from django.contrib.auth.hashers import check_password @@ -84,9 +83,11 @@ class User(AbstractBaseUser, PermissionsMixin): date_registered = models.DateTimeField(blank=True, null=True)# date_modified = models.DateTimeField(auto_now=True) #relations - country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, related_name='users') - city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True) - company = models.ForeignKey('company.Company', blank=True, null=True) + country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, + on_delete=models.PROTECT, related_name='users') + city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, + on_delete=models.PROTECT) + company = models.ForeignKey('company.Company', blank=True, null=True, on_delete=models.PROTECT) #other user information phone = models.PositiveIntegerField(verbose_name='Телефон', blank=True, null=True) position = models.CharField(verbose_name='Должность', max_length=255, blank=True) diff --git a/article/forms.py b/article/forms.py index 70edfb89..e96fbc0d 100644 --- a/article/forms.py +++ b/article/forms.py @@ -3,7 +3,7 @@ from django import forms from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError -from django.template.defaultfilters import slugify +from django.forms.util import ErrorList #functions from functions.translate import populate_all, fill_trans_fields_all from functions.files import check_tmp_files @@ -27,6 +27,8 @@ class ArticleForm(forms.Form): #creates select input with empty choices cause it will be filled with ajax tag = forms.MultipleChoiceField(label='Теги', required=False) + article_id = forms.CharField(required=False, widget=forms.HiddenInput()) + def __init__(self, *args, **kwargs): """ create dynamical translated fields fields @@ -69,7 +71,7 @@ class ArticleForm(forms.Form): article.author = data['author'] #create slug field from russian language - article.url = translit_with_separator(data['main_title_ru']) + article.url = translit_with_separator(data['main_title_ru']).lower() # uses because in the next loop data will be overwritten article.save() @@ -94,17 +96,14 @@ class ArticleForm(forms.Form): check_tmp_files(article, data['key']) - def clean_main_title_ru(self): - """ - check main title which must be unique because it generate slug field - """ - cleaned_data = super(ArticleForm, self).clean() - main_title_ru = cleaned_data.get('main_title_ru') - try: - article = Article.objects.get(url=translit_with_separator(main_title_ru)) - if (article.url == translit_with_separator(main_title_ru)): - return main_title_ru - except: - return main_title_ru - - raise ValidationError('Статья с таким названием уже существует') \ No newline at end of file + def clean(self): + id = self.cleaned_data.get('article_id') + main_title_ru = self.cleaned_data.get('main_title_ru') + + article = Article.objects.filter(url=translit_with_separator(main_title_ru)) + if article and str(article[0].id) != id: + msg = 'Статья с таким названием уже существует' + self._errors['main_title_ru'] = ErrorList([msg]) + del self.cleaned_data['main_title_ru'] + + return self.cleaned_data \ No newline at end of file diff --git a/article/models.py b/article/models.py index cab5850a..d8da9da1 100644 --- a/article/models.py +++ b/article/models.py @@ -13,7 +13,8 @@ class Article(TranslatableModel): url = models.SlugField(unique=True) theme = models.ManyToManyField('theme.Theme') tag = models.ManyToManyField('theme.Tag', related_name='tags',blank=True, null=True) - author = models.CharField(max_length=150, blank=True) + organiser = models.ForeignKey('organiser.Organiser', verbose_name='Автор', + on_delete=models.PROTECT, related_name='articles') #translated fields translations = TranslatedFields( diff --git a/article/views.py b/article/views.py index 2c748106..58623c9e 100644 --- a/article/views.py +++ b/article/views.py @@ -42,6 +42,7 @@ def article_change(request, url): #check if article_id exists else redirect to the list of cities article = Article.objects.get(url=url) file_form = FileModelForm(initial={'model': 'article.Article'}) + article_id = getattr(article, 'id') except: return HttpResponseRedirect('/article/all') @@ -59,6 +60,9 @@ def article_change(request, url): data['author'] = article.author data['theme'] = [item.id for item in article.theme.all()] data['tag'] = [item.id for item in article.tag.all()] + #hidden field + data['article_id'] = article_id + #data from translated fields for code, name in settings.LANGUAGES: obj = Article._meta.translations_model.objects.get(language_code = code,master__id=getattr(article, 'id')) #access to translated fields diff --git a/city/forms.py b/city/forms.py index 3a373f0e..e0204f26 100644 --- a/city/forms.py +++ b/city/forms.py @@ -3,6 +3,7 @@ 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 City from country.models import Country @@ -31,6 +32,8 @@ class CityForm(forms.Form): country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + city_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ @@ -79,7 +82,6 @@ class CityForm(forms.Form): else: city = City.objects.get(id=id) - city.url = translit_with_separator(data['name_ru']) city.phone_code = data['phone_code'] city.population = data['population'] if data.get('code_IATA'): @@ -88,8 +90,10 @@ class CityForm(forms.Form): city.country = Country.objects.get(id=data['country'].id)#.id cause select uses queryset # uses because in the next loop data will be overwritten + city.url = '%s-'%translit_with_separator(city.country.name) + translit_with_separator(data['name_ru']).lower() city.save() + #will be saved populated fields zero_fields = {} #fills all translated fields with data @@ -103,21 +107,20 @@ class CityForm(forms.Form): #save files check_tmp_files(city, data['key']) - def clean_name_ru(self): - """ - check name which must be unique because it generate slug field - """ - cleaned_data = super(CityForm, self).clean() - name_ru = cleaned_data.get('name_ru') - try: - city = City.objects.get(url=translit_with_separator(name_ru)) - if(city.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru - raise ValidationError('Город с таким названием уже существует') + def clean(self): + id = self.cleaned_data.get('city_id') + name_ru = self.cleaned_data.get('name_ru') + c = City.objects.get(pk=id) + city = City.objects.filter( + url='%s-%s'%(translit_with_separator(c.country.name), translit_with_separator(name_ru)) + ) + if city and str(city[0].id) != id: + msg = 'Город с таким названием уже существует' + self._errors['name_ru'] = ErrorList([msg]) + del self.cleaned_data['name_ru'] + return self.cleaned_data def clean_phone_code(self): """ diff --git a/city/models.py b/city/models.py index e11df6bc..8df1fc83 100644 --- a/city/models.py +++ b/city/models.py @@ -14,7 +14,12 @@ class City(TranslatableModel): Uses hvad.TranslatableModel which is child of django.db.models class """ - flags = [] + + try: + flags = [str(item.id) for item in Service.objects.all()] + except: + flags = [] + """ ids = [item.id for item in Service.objects.all() ] if len(ids): @@ -27,7 +32,7 @@ class City(TranslatableModel): services = BitField(flags=flags) url = models.SlugField(unique=True) - country = models.ForeignKey('country.Country', null=True) + country = models.ForeignKey('country.Country', null=True, on_delete=models.PROTECT) population = models.PositiveIntegerField(blank=True, null=True) phone_code = models.PositiveIntegerField(blank=True, null=True) code_IATA = models.ForeignKey(Iata, null=True) diff --git a/city/views.py b/city/views.py index 4982b53a..fc926079 100644 --- a/city/views.py +++ b/city/views.py @@ -51,8 +51,8 @@ def city_change(request, url): return HttpResponseRedirect('/city/all') else: #fill form with data from database - data = {'population' : c.population, - 'phone_code' : c.phone_code} + data = {'population' : c.population, 'phone_code' : c.phone_code, + 'city_id' : city_id} if c.country: data['country'] = c.country.id diff --git a/company/models.py b/company/models.py index b548f277..1df31e28 100644 --- a/company/models.py +++ b/company/models.py @@ -17,9 +17,10 @@ class Company(TranslatableModel): theme = models.ManyToManyField('theme.Theme', verbose_name='Отрасль', blank=True, null=True, related_name='companies') tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', blank=True, null=True, related_name='companies') - country = models.ForeignKey('country.Country', verbose_name='Страна', - blank=True, null=True, related_name='companies') - city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, related_name='companies') + country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, + on_delete=models.PROTECT, related_name='companies') + city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, + on_delete=models.PROTECT, related_name='companies') #address. uses LocationField. saves data in json format address = LocationField(verbose_name='Адрес', blank=True) diff --git a/conference/forms.py b/conference/forms.py index f64f3e07..332bf70f 100644 --- a/conference/forms.py +++ b/conference/forms.py @@ -2,7 +2,7 @@ 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 Conference, TimeTable, CURRENCY from country.models import Country @@ -52,6 +52,9 @@ class ConferenceCreateForm(forms.Form): max_price = forms.CharField(label='Максимальная цена', required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + conference_id = forms.CharField(required=False, widget=forms.HiddenInput()) + def __init__(self, *args, **kwargs): """ @@ -109,7 +112,7 @@ class ConferenceCreateForm(forms.Form): conference.tag.clear() #simple fields - conference.url = translit_with_separator(data['name_ru']) + conference.url = translit_with_separator(data['name_ru']).lower() conference.data_begin = data['data_begin'] conference.data_end = data['data_end'] conference.link = data['link'] @@ -152,22 +155,17 @@ class ConferenceCreateForm(forms.Form): #save files check_tmp_files(conference, data['key']) + def clean(self): + id = self.cleaned_data.get('conference_id') + name_ru = self.cleaned_data.get('name_ru') - def clean_name_ru(self): - """ - check name which must be unique because it generate slug field - """ - cleaned_data = super(ConferenceCreateForm, self).clean() - name_ru = cleaned_data.get('name_ru') - try: - conference = Conference.objects.get(url=translit_with_separator(name_ru)) - if (conference.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru - - raise ValidationError('Конференция с таким названием уже существует') + 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_web_page(self): """ diff --git a/conference/models.py b/conference/models.py index cf88ac9a..99efff1b 100644 --- a/conference/models.py +++ b/conference/models.py @@ -18,10 +18,10 @@ class Conference(TranslatableModel): data_begin = models.DateField(verbose_name='Дата начала') data_end = models.DateField(verbose_name='Дата окончания') #relations - country = models.ForeignKey('country.Country', verbose_name='Страна') - city = models.ForeignKey('city.City', verbose_name='Город') + country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT) + city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT) place = models.ForeignKey('place_conference.PlaceConference', verbose_name='Место проведения', - blank=True, null=True, related_name='conference_place') + blank=True, null=True, on_delete=models.PROTECT, related_name='conference_place') theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики', related_name='conference_themes') tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', diff --git a/conference/views.py b/conference/views.py index 2249898d..a95bfdd7 100644 --- a/conference/views.py +++ b/conference/views.py @@ -93,8 +93,8 @@ def conference_change(request, url): #fill form with data from database data = {'web_page':conference.web_page, 'foundation_year': conference.foundation_year, 'data_begin':conference.data_begin, 'data_end':conference.data_end, 'currency':conference.currency, - 'tax':conference.tax, 'min_price':conference.min_price, - 'max_price':conference.max_price, 'link':conference.link} + 'tax':conference.tax, 'min_price':conference.min_price, 'max_price':conference.max_price, + 'link':conference.link, 'conference_id':conference.id} if conference.country: data['country'] = conference.country.id diff --git a/country/forms.py b/country/forms.py index df4590d1..afb89485 100644 --- a/country/forms.py +++ b/country/forms.py @@ -3,6 +3,7 @@ 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 @@ -57,6 +58,8 @@ class CountryForm(forms.Form): #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 ): @@ -124,7 +127,7 @@ class CountryForm(forms.Form): country.language.clear() country.currency.clear() - country.url = translit_with_separator(data['name_ru']) + country.url = translit_with_separator(data['name_ru']).lower() country.population = data['population'] country.teritory = data['teritory'] country.timezone = data['timezone'] @@ -163,22 +166,18 @@ class CountryForm(forms.Form): #save files check_tmp_files(country, data['key']) - def clean_name_ru(self): - """ - check name which must be unique because it generate slug field - """ - cleaned_data = super(CountryForm, self).clean() - name_ru = cleaned_data.get('name_ru') - try: - country = Country.objects.get(url=translit_with_separator(name_ru)) - if (country.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru + def clean(self): + id = self.cleaned_data.get('country_id') + name_ru = self.cleaned_data.get('name_ru') - raise ValidationError('Страна с таким названием уже существует') + 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 self.cleaned_data['name_ru'] + return self.cleaned_data def clean_phone_code(self): """ diff --git a/country/models.py b/country/models.py index 131eff3b..e9c5a4b4 100644 --- a/country/models.py +++ b/country/models.py @@ -17,20 +17,21 @@ class Country(TranslatableModel): Uses hvad.TranslatableModel which is child of django.db.models class """ - flags = [] - - ids = [str(item.id) for item in Service.objects.all() ] + try: + flags = [str(item.id) for item in Service.objects.all()] + except: + flags = [] #max = sorted(ids)[-1] #for i in range(max): # flags.append(str(i)) - services = BitField(flags=ids) + services = BitField(flags=flags) REGIONS =('europa', 'asia', 'america', 'africa') url = models.SlugField(unique=True) - capital = models.ForeignKey(City,blank=True, null=True, related_name='capital') + capital = models.ForeignKey(City,blank=True, null=True, on_delete=models.PROTECT, related_name='capital') population = models.PositiveIntegerField(blank=True, null=True) teritory = models.PositiveIntegerField(blank=True, null=True) timezone = models.FloatField(blank=True, null=True) diff --git a/country/urls.py b/country/urls.py index 043a4859..03ce9be1 100644 --- a/country/urls.py +++ b/country/urls.py @@ -3,6 +3,7 @@ from django.conf.urls import patterns, include, url urlpatterns = patterns('country.views', url(r'^add.*/$', 'country_add'), + url(r'^delete/(.*)/$', 'country_delete'), url(r'^change/(.*)/$', 'country_change'), url(r'^all/$', 'country_all'), ) \ No newline at end of file diff --git a/country/views.py b/country/views.py index 79e0fc23..210c79d3 100644 --- a/country/views.py +++ b/country/views.py @@ -28,6 +28,38 @@ def country_add(request): """ return add_object_with_file(request, CountryForm, 'country_add.html', '/country/all/') +def country_delete(request, url): + try: + c = Country.objects.get(url=url) + country_id = getattr(c, 'id') + except: + return HttpResponseRedirect('/country/all') + c.delete() + + return objects_list(request, Country, 'country_all.html') + + + +def objects_list(request, Model, template, item_per_page=10): + """ + Return template with all objects of model Model + Model - objects Model + item_per_page - how many objects view in the one page + """ + list = Model.objects.all() + paginator = Paginator(list, item_per_page) + page = request.GET.get('page') + try: + objects = paginator.page(page) + except PageNotAnInteger: + # If page is not an integer, deliver first page. + objects = paginator.page(1) + except EmptyPage: + # If page is out of range (e.g. 9999), deliver last page of results. + objects = paginator.page(paginator._num_pages) + return render_to_response(template, {'objects': objects}) + + @login_required def country_change(request, url): @@ -58,7 +90,7 @@ def country_change(request, url): else: #fill form with data from database data = {'population' : c.population, 'teritory' : c.teritory, #data from NOT translated fields - 'timezone' : c.timezone, 'region' : c.region, + 'timezone' : c.timezone, 'region' : c.region, 'country_id' : country_id, 'phone_code' : c.phone_code, 'time_delivery' : c.time_delivery} if c.capital: diff --git a/exposition/forms.py b/exposition/forms.py index ec3a65c6..44e4fc2d 100644 --- a/exposition/forms.py +++ b/exposition/forms.py @@ -3,6 +3,7 @@ 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 Exposition, TimeTable, AUDIENCE1, CURRENCY from country.models import Country @@ -63,6 +64,8 @@ class ExpositionCreateForm(forms.Form): registration_payment = forms.CharField(label='Регистрационны взнос', required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + exposition_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): @@ -115,7 +118,7 @@ class ExpositionCreateForm(forms.Form): exposition.tag.clear() #simple fields - exposition.url = translit_with_separator(data['name_ru']) + exposition.url = translit_with_separator(data['name_ru']).lower() exposition.data_begin = data['data_begin'] exposition.data_end = data['data_end'] exposition.periodic = data['periodic'] @@ -165,21 +168,17 @@ class ExpositionCreateForm(forms.Form): #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 + def clean(self): + id = self.cleaned_data.get('exposition_id') + name_ru = self.cleaned_data.get('name_ru') - raise ValidationError('Выставка с таким названием уже существует') + exposition = Exposition.objects.filter(url=translit_with_separator(name_ru)) + if exposition and str(exposition[0].id) != id: + msg = 'Выставка с таким названием уже существует' + self._errors['name_ru'] = ErrorList([msg]) + del self.cleaned_data['name_ru'] + return self.cleaned_data def clean_web_page(self): """ diff --git a/exposition/models.py b/exposition/models.py index 62d94d50..9dec5d7f 100644 --- a/exposition/models.py +++ b/exposition/models.py @@ -21,10 +21,10 @@ class Exposition(TranslatableModel): data_begin = models.DateField(verbose_name='Дата начала') data_end = models.DateField(verbose_name='Дата окончания') #relations - country = models.ForeignKey('country.Country', verbose_name='Страна') - city = models.ForeignKey('city.City', verbose_name='Город') + country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT) + city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT) place = models.ForeignKey('place_exposition.PlaceExposition', verbose_name='Место проведения', - blank=True, null=True, related_name='exposition_place') + blank=True, null=True, on_delete=models.PROTECT, related_name='exposition_place') theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики', related_name='exposition_themes') tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', diff --git a/exposition/views.py b/exposition/views.py index 7260b4d8..56a346e3 100644 --- a/exposition/views.py +++ b/exposition/views.py @@ -97,7 +97,7 @@ def exposition_change(request, url): 'max_closed_area':exposition.max_closed_area, 'min_closed_equipped_area':exposition.min_closed_equipped_area, 'max_closed_equipped_area':exposition.max_closed_equipped_area, 'min_open_area':exposition.min_open_area, 'max_open_area':exposition.max_open_area, - 'registration_payment':exposition.registration_payment} + 'registration_payment':exposition.registration_payment, 'exposition_id':exposition.id} if exposition.country: data['country'] = exposition.country.id diff --git a/functions/form_check.py b/functions/form_check.py index 2b14aec5..39c60882 100644 --- a/functions/form_check.py +++ b/functions/form_check.py @@ -19,10 +19,9 @@ def translit_with_separator(string, separator='-'): usage: translit_with_separator('введите, слово', '_') return 'vvedite_slovo' - string must be unicode - """ - + #make string unicode + string = u'%s'%string #make string translit st = pytils.translit.translify(string) #replace "bad" symbols for '-'symbol diff --git a/news/models.py b/news/models.py index 31e8bfe4..68df57bd 100644 --- a/news/models.py +++ b/news/models.py @@ -18,7 +18,8 @@ class News(TranslatableModel): type = EnumField(values=TYPES) theme = models.ManyToManyField('theme.Theme', verbose_name='Тема') tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', blank=True, null=True) - organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True) + organiser = models.ForeignKey('organiser.Organiser', verbose_name='Организатор', blank=True, null=True, + on_delete=models.PROTECT) paid = models.BooleanField(default=0) translations = TranslatedFields( diff --git a/organiser/models.py b/organiser/models.py index c3300531..476e0d77 100644 --- a/organiser/models.py +++ b/organiser/models.py @@ -20,8 +20,10 @@ class Organiser(TranslatableModel): url = models.SlugField(verbose_name='URL', blank=True) #relations - country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True) - city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True) + country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, + on_delete=models.PROTECT) + city = models.ForeignKey('city.City', verbose_name='Город', blank=True, null=True, + on_delete=models.PROTECT,) theme = models.ManyToManyField('theme.Theme', verbose_name='Отрасль', blank=True, null=True) tag = models.ManyToManyField('theme.Tag', verbose_name='Теги', blank=True, null=True) #address. uses LocationField. saves data in json format diff --git a/place_conference/forms.py b/place_conference/forms.py index 42480c6c..ae556959 100644 --- a/place_conference/forms.py +++ b/place_conference/forms.py @@ -4,6 +4,7 @@ from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError from django.core.validators import validate_email, URLValidator +from django.forms.util import ErrorList #models from models import PlaceConference, Hall, CONFERENCE_TYPE from country.models import Country @@ -64,6 +65,8 @@ class ConferenceForm(forms.Form): hotel = forms.BooleanField(label='Гостиница', required=False) # key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + place_conference_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ @@ -112,7 +115,7 @@ class ConferenceForm(forms.Form): place_conference = PlaceConference.objects.get(id=id) #simple fields - place_conference.url = translit_with_separator(data['name_ru']) + place_conference.url = translit_with_separator(data['name_ru']).lower() place_conference.type = data['type'] place_conference.address = data['address'] place_conference.phone = data['phone'] @@ -153,20 +156,17 @@ class ConferenceForm(forms.Form): return PlaceConference.objects.get(id=place_conference_id) - def clean_name_ru(self): - """ - check name which must be unique because it generate slug field - """ + def clean(self): + id = self.cleaned_data.get('place_conference_id') name_ru = self.cleaned_data.get('name_ru') - try: - place_conference = PlaceConference.objects.get(url=translit_with_separator(name_ru)) - if (place_conference.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru - raise ValidationError('Место проведения с таким названием уже существует') + place_conference = PlaceConference.objects.filter(url=translit_with_separator(name_ru)) + if place_conference and str(place_conference[0].id) != id: + msg = 'Место проведения с таким названием уже существует' + self._errors['name_ru'] = ErrorList([msg]) + del self.cleaned_data['name_ru'] + return self.cleaned_data def clean_web_page(self): """ diff --git a/place_conference/models.py b/place_conference/models.py index 058af8c0..2829c1bd 100644 --- a/place_conference/models.py +++ b/place_conference/models.py @@ -16,8 +16,8 @@ class PlaceConference(TranslatableModel): """ url = models.SlugField(unique=True) - country = models.ForeignKey('country.Country', null=True) - city = models.ForeignKey('city.City', null=True) + country = models.ForeignKey('country.Country', on_delete=models.PROTECT) + city = models.ForeignKey('city.City', on_delete=models.PROTECT) #type uses EnumField for creating Enum type field in Mysql database type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE]) #information diff --git a/place_conference/views.py b/place_conference/views.py index 303c401b..9611479c 100644 --- a/place_conference/views.py +++ b/place_conference/views.py @@ -124,7 +124,7 @@ def conference_change(request, url): 'exposition_hall': place.exposition_hall, 'exp_hall_area': place.exp_hall_area, 'wifi': place.wifi, 'multimedia_equipment': place.multimedia_equipment, 'conference_call':place.conference_call, 'translate_equipment': place.translate_equipment, 'banquet_hall': place.banquet_hall, - 'catering': place.catering, 'hotel': place.hotel} + 'catering': place.catering, 'hotel': place.hotel, 'place_conference_id':place.id} if place.country: data['country'] = place.country.id diff --git a/place_exposition/forms.py b/place_exposition/forms.py index 0b2526a6..9d8e1bf7 100644 --- a/place_exposition/forms.py +++ b/place_exposition/forms.py @@ -4,6 +4,7 @@ from django.conf import settings from ckeditor.widgets import CKEditorWidget from django.core.exceptions import ValidationError from django.core.validators import validate_email, URLValidator +from django.forms.util import ErrorList #models from models import PlaceExposition, EXPOSITION_TYPE, Hall from country.models import Country @@ -69,6 +70,8 @@ class ExpositionForm(forms.Form): mobile_application = forms.BooleanField(label='Мобильное приложение', required=False) # key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + place_exposition_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ @@ -112,7 +115,7 @@ class ExpositionForm(forms.Form): place_exposition = PlaceExposition.objects.get(id=id) #simple fields - place_exposition.url = translit_with_separator(data['name_ru']) + place_exposition.url = translit_with_separator(data['name_ru']).lower() place_exposition.type = data['type'] place_exposition.address = data['address'] place_exposition.phone = data['phone'] @@ -159,22 +162,17 @@ class ExpositionForm(forms.Form): return PlaceExposition.objects.get(id=place_exposition_id) + def clean(self): + id = self.cleaned_data.get('place_exposition_id') + name_ru = self.cleaned_data.get('name_ru') - def clean_name_ru(self): - """ - check name which must be unique because it generate slug field - """ - cleaned_data = super(ExpositionForm, self).clean() - name_ru = cleaned_data.get('name_ru') - try: - place_exposittion = PlaceExposition.objects.get(url=translit_with_separator(name_ru)) - if(place_exposittion.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru - - raise ValidationError('Место проведения с таким названием уже существует') + place_exposition = PlaceExposition.objects.filter(url=translit_with_separator(name_ru)) + if place_exposition and str(place_exposition[0].id) != id: + msg = 'Место проведения с таким названием уже существует' + self._errors['name_ru'] = ErrorList([msg]) + del self.cleaned_data['name_ru'] + return self.cleaned_data def clean_web_page(self): """ diff --git a/place_exposition/models.py b/place_exposition/models.py index ab39103f..71f0fb25 100644 --- a/place_exposition/models.py +++ b/place_exposition/models.py @@ -16,8 +16,8 @@ class PlaceExposition(TranslatableModel): """ url = models.SlugField(unique=True) - country = models.ForeignKey('country.Country') - city = models.ForeignKey('city.City') + country = models.ForeignKey('country.Country', on_delete=models.PROTECT) + city = models.ForeignKey('city.City', on_delete=models.PROTECT) #type uses EnumField for creating Enum type field in Mysql database type = EnumField(values = [item1 for item1, item2 in EXPOSITION_TYPE]) #information diff --git a/place_exposition/views.py b/place_exposition/views.py index 07380af8..25593f0a 100644 --- a/place_exposition/views.py +++ b/place_exposition/views.py @@ -128,7 +128,8 @@ def exposition_change(request, url): 'disabled_service': place.disabled_service, 'conference_centre': place.conference_centre, 'business_centre': place.business_centre, 'online_registration': place.online_registration, 'cafe': place.cafe, 'terminals': place.terminals, 'parking': place.parking, - 'press_centre': place.press_centre, 'mobile_application': place.mobile_application} + 'press_centre': place.press_centre, 'mobile_application': place.mobile_application, + 'place_exposition_id':place.id} if place.country: data['country'] = place.country.id diff --git a/review/models.py b/review/models.py index 4c3982dc..fb11304e 100644 --- a/review/models.py +++ b/review/models.py @@ -10,20 +10,19 @@ from django.contrib.contenttypes import generic class Review(models.Model): """ Create Review model - Uses hvad.TranslatableModel which is child of django.db.models class Uses ContentType for connection Review with another models content_type = model which linked Review object object_id = specific object of model which linked Review object """ - + #connection with models content_type = models.ForeignKey(ContentType, null=True) object_id = models.PositiveIntegerField(blank=True, null=True) object = generic.GenericForeignKey(content_type, object_id) - - user = models.ForeignKey('accounts.User', related_name='reviews') + user = models.ForeignKey('accounts.User', blank=True, null=True, + on_delete=models.PROTECT, related_name='reviews') comment = models.TextField(verbose_name='Отзыв') rating = models.SmallIntegerField(verbose_name='Оценка', blank=True, null=True) diff --git a/seminar/forms.py b/seminar/forms.py index 3ebb1666..9bcf12bb 100644 --- a/seminar/forms.py +++ b/seminar/forms.py @@ -3,6 +3,7 @@ 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 Seminar, CURRENCY from country.models import Country @@ -50,6 +51,8 @@ class SeminarCreateForm(forms.Form): max_price = forms.CharField(label='Максимальная цена', required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + seminar_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ @@ -101,7 +104,7 @@ class SeminarCreateForm(forms.Form): seminar.tag.clear() #simple fields - seminar.url = translit_with_separator(data['name_ru']) + seminar.url = translit_with_separator(data['name_ru']).lower() seminar.data_begin = data['data_begin'] seminar.data_end = data['data_end'] seminar.link = data['link'] @@ -143,20 +146,17 @@ class SeminarCreateForm(forms.Form): #save files check_tmp_files(seminar, data['key']) - def clean_name_ru(self): - """ - check main title which must be unique because it generate slug field - """ - cleaned_data = super(SeminarCreateForm, self).clean() - name_ru = cleaned_data.get('name_ru') - try: - seminar = Seminar.objects.get(url=translit_with_separator(name_ru)) - if(seminar.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru + def clean(self): + id = self.cleaned_data.get('seminar_id') + name_ru = self.cleaned_data.get('name_ru') + + seminar = Seminar.objects.filter(url=translit_with_separator(name_ru)) + if seminar and str(seminar[0].id) != id: + msg = 'Семинар с таким названием уже существует' + self._errors['name_ru'] = ErrorList([msg]) + del self.cleaned_data['name_ru'] - raise ValidationError('Семинар с таким названием уже существует') + return self.cleaned_data def clean_web_page(self): diff --git a/seminar/models.py b/seminar/models.py index 52ce2b94..397455aa 100644 --- a/seminar/models.py +++ b/seminar/models.py @@ -18,8 +18,8 @@ class Seminar(TranslatableModel): data_begin = models.DateTimeField(verbose_name='Дата начала') data_end = models.DateTimeField(verbose_name='Дата окончания') #relations - country = models.ForeignKey('country.Country', verbose_name='Страна') - city = models.ForeignKey('city.City', verbose_name='Город') + country = models.ForeignKey('country.Country', verbose_name='Страна', on_delete=models.PROTECT) + city = models.ForeignKey('city.City', verbose_name='Город', on_delete=models.PROTECT) address = LocationField(verbose_name='Адрес', blank=True) theme = models.ManyToManyField('theme.Theme', verbose_name='Тематики', related_name='seminar_themes') diff --git a/seminar/views.py b/seminar/views.py index 056110cb..0fbf0679 100644 --- a/seminar/views.py +++ b/seminar/views.py @@ -94,7 +94,7 @@ def seminar_change(request, url): data = {'web_page':seminar.web_page, 'foundation_year': seminar.foundation_year, 'data_begin':seminar.data_begin, 'data_end':seminar.data_end, 'currency':seminar.currency, 'tax':seminar.tax, 'min_price':seminar.min_price, 'link':seminar.link, - 'max_price':seminar.max_price, 'address':seminar.address} + 'max_price':seminar.max_price, 'address':seminar.address, 'seminar_id':seminar.id} if seminar.country: data['country'] = seminar.country.id diff --git a/service/admin.py b/service/admin.py index af2cf678..5fd9f69f 100644 --- a/service/admin.py +++ b/service/admin.py @@ -1,19 +1,9 @@ # -*- coding: utf-8 -*- from django.contrib import admin from hvad.admin import TranslatableAdmin -from models import Service, Review -from bitfield import BitField -from bitfield.forms import BitFieldCheckboxSelectMultiple -from bitfield import BitField -from bitfield.forms import BitFieldCheckboxSelectMultiple +from models import Service class ServiceAdmin(TranslatableAdmin): - formfield_overrides = { - BitField: {'widget': BitFieldCheckboxSelectMultiple}, -} - -class ReviewAdmin(TranslatableAdmin): pass -admin.site.register(Service, ServiceAdmin) -admin.site.register(Review, ReviewAdmin) +admin.site.register(Service, ServiceAdmin) \ No newline at end of file diff --git a/service/forms.py b/service/forms.py index 0f79ca5e..1f278942 100644 --- a/service/forms.py +++ b/service/forms.py @@ -2,18 +2,15 @@ from django.db.models import F from django import forms from django.conf import settings +from django.forms.util import ErrorList from ckeditor.widgets import CKEditorWidget -from django.core.exceptions import ValidationError from functions.translate import populate_all, fill_trans_fields_all #models -from models import Review, Service +from models import Service from country.models import Country, City from functions.form_check import translit_with_separator -from django.forms.util import ErrorList - - class ServiceForm(forms.Form): europa = forms.ModelMultipleChoiceField(queryset=Country.objects.filter(region='europa'), required=False, @@ -26,7 +23,7 @@ class ServiceForm(forms.Form): widget=forms.CheckboxSelectMultiple()) -# city = forms.MultipleChoiceField(choices=cities) + city = forms.MultipleChoiceField(required=False, choices="") url = forms.CharField(label='url', required=False) @@ -71,7 +68,8 @@ class ServiceForm(forms.Form): service = Service.objects.get(id=id) - service.url = translit_with_separator(data['url']) if data['url'] else translit_with_separator(data['name_ru']) + service.url = translit_with_separator(data['url']).lower() if data['url']\ + else translit_with_separator(data['name_ru'].lower()) service.price = data['price']+' '+data['currency']#%s %s'%(data['price'], data['currency']) # uses because in the next loop data will be overwritten service.save() @@ -83,6 +81,8 @@ class ServiceForm(forms.Form): #autopopulate #populate empty fields and fields which was already populated + + service_id = getattr(service, 'id') populate_all(Service, data, service_id, zero_fields) @@ -91,102 +91,29 @@ class ServiceForm(forms.Form): countries += [item.id for item in data['america']] countries += [item.id for item in data['africa']] + cities = [item for item in data['city']] + #add service to checked countries + Country.objects.filter(id__in=countries).\ update(services = F('services').bitor(getattr(Country.services, str(service.id))) ) Country.objects.exclude(id__in=countries).\ update(services = F('services').bitand(~getattr(Country.services, str(service.id)))) - - - + #add service to checked cities + City.objects.filter(id__in=cities).\ + update(services = F('services').bitor(getattr(City.services, str(service.id))) ) + City.objects.exclude(id__in=cities).\ + update(services = F('services').bitand(~getattr(City.services, str(service.id)))) def clean(self): id = self.cleaned_data.get('service_id') url = self.cleaned_data.get('url') - try: - service = Service.objects.get(url=translit_with_separator(url)) - if (str(service.id) != str(id)): - msg = 'Такой урл уже занят' - self._errors['url'] = ErrorList([msg]) - del self.cleaned_data['url'] - except: - pass - - return self.cleaned_data - - - def clean_url(self): - """ - check name which must be unique because it generate slug field - """ - cleaned_data = super(ServiceForm, self).clean() - url = cleaned_data.get('url') - id = cleaned_data.get('service_id') - try: - service = Service.objects.get(url=translit_with_separator(url)) - if (translit_with_separator(url) == service.url): - return url - except: - return url - raise ValidationError('Такой урл уже занят') - - - -class ReviewForm(forms.ModelForm): - rating = forms.ChoiceField(label='Оценка', choices=[(n, n) for n in range(1,6)], widget=forms.RadioSelect()) - comment = forms.CharField(label='Комментарий', widget=CKEditorWidget) - class Meta: - model = Review - - -""" -class ReviewForm(forms.Form): - web_page = forms.CharField(label='Сайт', required=False) - rating = forms.ChoiceField(label=('Оценка'), choices=[(n,n) for n in range(1,6)],widget=forms.RadioSelect()) - - def __init__(self, *args, **kwargs): - super(ReviewForm, 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['company_%s' % code] = forms.CharField(label='Компания', required=required) - self.fields['contact_%s' % code] = forms.CharField(label='Контакт', required=required) - self.fields['comment_%s' % code] = forms.CharField(label='Коментарий', required=required, widget=CKEditorWidget) - - services = [(item.id, item.name) for item in Service.objects.all()] - self.fields['service'] = forms.ChoiceField(label='Сервис', choices=services) - - def save(self, id=None): - data = self.cleaned_data - - if not id: - review = Review() - else: - review = Review.objects.get(id=id) - - review.rating = data['rating'] - review.web_page = data['web_page'] - - if data.get('service'): - review.service = Service.objects.get(id=data['service']) - - review.save() - - - #populate fields with zero language - zero_fields = {} - - fill_trans_fields_all(Review, review, data, id, zero_fields) - - #autopopulate - #populate empty fields and fields which was already populated - review_id = getattr(review, 'id') - populate_all(Review, data, review_id, zero_fields) + service = Service.objects.filter(url=translit_with_separator(url)) + if service and str(service[0].id) != id: + msg = 'Такой урл уже занят' + self._errors['url'] = ErrorList([msg]) + del self.cleaned_data['url'] -""" \ No newline at end of file + return self.cleaned_data \ No newline at end of file diff --git a/service/models.py b/service/models.py index 902e3fb5..cc11ff2b 100644 --- a/service/models.py +++ b/service/models.py @@ -1,20 +1,11 @@ # -*- coding: utf-8 -*- from django.db import models from hvad.models import TranslatableModel, TranslatedFields -from bitfield import BitField -#from country.models import Country, City - class Service(TranslatableModel): - #event = models.ManyToManyField() + url = models.SlugField(unique=True) - """ - countries = [str(item.id) for item in Country.objects.all()] - cities = [str(item.id) for item in City.objects.all()] - country = BitField(flags=countries) - city = BitField(flags=cities) - """ price = models.CharField(max_length=20, blank=True) params = models.CharField(max_length=255, blank=True) #translated fields @@ -30,12 +21,4 @@ class Service(TranslatableModel): ) def __unicode__(self): - return self.lazy_translation_getter('name', self.pk) - -class Review(models.Model): - service = models.ForeignKey(Service, related_name='services') - web_page = models.CharField(max_length=50, blank=True) - rating = models.SmallIntegerField() - company = models.CharField(verbose_name='Компания', max_length=255) - contact= models.CharField(verbose_name='Контакты', max_length=255) - comment = models.TextField(verbose_name='Коментарий') \ No newline at end of file + return self.lazy_translation_getter('name', self.pk) \ No newline at end of file diff --git a/service/urls.py b/service/urls.py index e72a1681..24865984 100644 --- a/service/urls.py +++ b/service/urls.py @@ -5,13 +5,8 @@ urlpatterns = patterns('', url(r'^add.*/$', 'service.views.service_add'), url(r'^change/(.*)/$', 'service.views.service_change'), url(r'^all/$', 'service.views.service_all'), - + #ajax url(r'^get_city/$', 'service.views.get_city'), url(r'^get_country/$', 'service.views.get_country'), - url(r'^review/add.*/$', 'service.views.review_add'), - url(r'^review/change/(?P\d+).*/$', 'service.views.review_change'), - url(r'^review/all/$', 'service.views.review_all'), - - ) \ No newline at end of file diff --git a/service/views.py b/service/views.py index 3c143e9e..ae58f719 100644 --- a/service/views.py +++ b/service/views.py @@ -1,13 +1,12 @@ # -*- coding: utf-8 -*- from django.shortcuts import render_to_response -from django.http import HttpResponseRedirect, HttpResponse +from django.http import HttpResponseRedirect from django.core.context_processors import csrf from django.conf import settings -from django.contrib.contenttypes.models import ContentType from django.contrib.auth.decorators import login_required #models and forms -from models import Service, Review -from forms import ServiceForm, ReviewForm +from models import Service +from forms import ServiceForm from country.models import Country from city.models import City #custom views @@ -20,14 +19,6 @@ def service_all(request): """ return objects_list(request, Service, 'service_all.html') - -def review_all(request): - """ - return list of all reviews with pagination - """ - return objects_list(request, Review, 'review_all.html') - - @login_required def service_change(request, url): try: @@ -37,6 +28,8 @@ def service_change(request, url): return HttpResponseRedirect('/service/all') if request.POST: form = ServiceForm(request.POST) + form.fields['city'].choices = [(item.id, item.name) for item in City.objects.all()] + if form.is_valid(): form.save(service_id) @@ -100,49 +93,6 @@ def service_add(request): return render_to_response('service_add.html', args) - -@login_required -def review_add(request): - if request.POST: - form = ReviewForm(request.POST) - if form.is_valid(): - form.save() - return HttpResponseRedirect('/service/review/all') - else: - form = ReviewForm() - - args = {} - args.update(csrf(request)) - - args['form'] = form - args['languages'] = settings.LANGUAGES - - return render_to_response('review_add.html', args) - - -@login_required -def review_change(request, review_id): - try: - review = Review.objects.get(id=review_id) - except: - return HttpResponseRedirect('/service/review/all') - - if request.POST: - form = ReviewForm(request.POST, instance=review) - if form.is_valid(): - form.save() - return HttpResponseRedirect('/service/review/all') - else: - form = ReviewForm(instance=review) - - args = {} - args.update(csrf(request)) - - args['form'] = form - args['languages'] = settings.LANGUAGES - - return render_to_response('review_add.html', args) - def get_country(request): if request.GET: country_region = request.GET['region'] diff --git a/templates/admin/article/article_add.html b/templates/admin/article/article_add.html index c32e86b1..b97a8623 100644 --- a/templates/admin/article/article_add.html +++ b/templates/admin/article/article_add.html @@ -28,8 +28,10 @@

Основная информация

- {# Hidden inputs uses for comparing with TmpFile objects #} + {# Hidden input uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.article_id }} {# main_title #} {% with field='main_title' form=form languages=languages %} diff --git a/templates/admin/city/city_add.html b/templates/admin/city/city_add.html index ab2fa300..3df89b78 100644 --- a/templates/admin/city/city_add.html +++ b/templates/admin/city/city_add.html @@ -29,6 +29,8 @@
{# Hidden inputs uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.city_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/conference/conference_add.html b/templates/admin/conference/conference_add.html index fdf2288e..62221ddf 100644 --- a/templates/admin/conference/conference_add.html +++ b/templates/admin/conference/conference_add.html @@ -53,6 +53,8 @@
{# Hidden inputs uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.conference_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/country/country_add.html b/templates/admin/country/country_add.html index 3a470126..dfe386b6 100644 --- a/templates/admin/country/country_add.html +++ b/templates/admin/country/country_add.html @@ -28,8 +28,10 @@

Основная информация

- {# Hidden inputs uses for comparing with TmpFile objects #} + {# Hidden input uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.country_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/country/country_all.html b/templates/admin/country/country_all.html index b49da469..97ee386f 100644 --- a/templates/admin/country/country_all.html +++ b/templates/admin/country/country_all.html @@ -31,6 +31,9 @@ Displays lists of all countries in the table Изменить + + Удалить + diff --git a/templates/admin/exposition/exposition_add.html b/templates/admin/exposition/exposition_add.html index 8d9cefc8..4d544231 100644 --- a/templates/admin/exposition/exposition_add.html +++ b/templates/admin/exposition/exposition_add.html @@ -57,6 +57,8 @@
{# Hidden inputs uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.exposition_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/place_conference/place_conference_add.html b/templates/admin/place_conference/place_conference_add.html index a210c34d..54cd9b16 100644 --- a/templates/admin/place_conference/place_conference_add.html +++ b/templates/admin/place_conference/place_conference_add.html @@ -37,6 +37,8 @@
{# Hidden input uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.place_conference_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/place_exposition/place_exposition_add.html b/templates/admin/place_exposition/place_exposition_add.html index ad87890f..77507041 100644 --- a/templates/admin/place_exposition/place_exposition_add.html +++ b/templates/admin/place_exposition/place_exposition_add.html @@ -35,6 +35,8 @@
{# Hidden input uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.place_exposition_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/seminar/seminar_add.html b/templates/admin/seminar/seminar_add.html index 397f6935..5ce27776 100644 --- a/templates/admin/seminar/seminar_add.html +++ b/templates/admin/seminar/seminar_add.html @@ -54,6 +54,8 @@
{# Hidden inputs uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.seminar_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/admin/service/checkbox_option.html b/templates/admin/service/checkbox_option.html index d0f1ced0..1274618d 100644 --- a/templates/admin/service/checkbox_option.html +++ b/templates/admin/service/checkbox_option.html @@ -2,7 +2,7 @@ {% for item in options %}
  • {% endfor %} diff --git a/templates/admin/theme/theme_all.html b/templates/admin/theme/theme_all.html index 49430d07..d8fb2be3 100644 --- a/templates/admin/theme/theme_all.html +++ b/templates/admin/theme/theme_all.html @@ -25,7 +25,7 @@ {{ item.main_title }} - + Изменить diff --git a/templates/admin/webinar/webinar_add.html b/templates/admin/webinar/webinar_add.html index 557880ae..784c19d7 100644 --- a/templates/admin/webinar/webinar_add.html +++ b/templates/admin/webinar/webinar_add.html @@ -49,6 +49,8 @@
    {# Hidden inputs uses for comparing with TmpFile objects #} {{ form.key }} + {# Hidden input uses in clean method for checking url #} + {{ form.webinar_id }} {# name #} {% with field='name' form=form languages=languages %} diff --git a/templates/base.html b/templates/base.html index 75100313..4e1c2cf2 100644 --- a/templates/base.html +++ b/templates/base.html @@ -130,8 +130,7 @@
  • Город
  • Тематики
  • Теги
  • -
  • Услуги
  • -
  • Отзывы к услугам
  • +
  • Услуги
  • Настройки
  • diff --git a/theme/models.py b/theme/models.py index ae6de072..61bb6332 100644 --- a/theme/models.py +++ b/theme/models.py @@ -43,7 +43,7 @@ class Tag(TranslatableModel): Uses hvad.TranslatableModel which is child of django.db.models class """ - theme = models.ForeignKey(Theme, related_name='themes') + theme = models.ForeignKey(Theme, on_delete=models.PROTECT, related_name='themes') #translated fields translations = TranslatedFields( name = models.CharField(max_length=100), diff --git a/webinar/forms.py b/webinar/forms.py index 0eca5c12..4553a662 100644 --- a/webinar/forms.py +++ b/webinar/forms.py @@ -3,6 +3,7 @@ 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 Webinar, CURRENCY from theme.models import Theme @@ -41,6 +42,8 @@ class WebinarCreateForm(forms.Form): max_price = forms.CharField(label='Максимальная цена', required=False) #field for comparing tmp files key = forms.CharField(required=False, widget=forms.HiddenInput()) + # + webinar_id = forms.CharField(required=False, widget=forms.HiddenInput()) def __init__(self, *args, **kwargs): """ @@ -96,7 +99,7 @@ class WebinarCreateForm(forms.Form): webinar.tag.clear() #simple fields - webinar.url = translit_with_separator(data['name_ru']) + webinar.url = translit_with_separator(data['name_ru']).lower() webinar.data_begin = data['data_begin'] webinar.link = data['link'] webinar.web_page= data['web_page'] @@ -128,21 +131,17 @@ class WebinarCreateForm(forms.Form): #save files check_tmp_files(webinar, data['key']) - def clean_name_ru(self): - """ - check main title which must be unique because it generate slug field - """ - cleaned_data = super(WebinarCreateForm, self).clean() - name_ru = cleaned_data.get('name_ru') - try: - webinar = Webinar.objects.get(url=translit_with_separator(name_ru)) - if (webinar.url == translit_with_separator(name_ru)): - return name_ru - except: - return name_ru + def clean(self): + id = self.cleaned_data.get('webinar_id') + name_ru = self.cleaned_data.get('name_ru') - raise ValidationError('Вебинар с таким названием уже существует') + webinar = Webinar.objects.filter(url=translit_with_separator(name_ru)) + if webinar and str(webinar[0].id) != id: + msg = 'Вебинар с таким названием уже существует' + self._errors['name_ru'] = ErrorList([msg]) + del self.cleaned_data['name_ru'] + return self.cleaned_data def clean_web_page(self): """ diff --git a/webinar/urls.py b/webinar/urls.py index 8a4da554..6aeec217 100644 --- a/webinar/urls.py +++ b/webinar/urls.py @@ -3,7 +3,6 @@ from django.conf.urls import patterns, include, url urlpatterns = patterns('', url(r'^add.*/$', 'webinar.views.webinar_add'), - url(r'^change/(.*)/$', 'webinar.views.webinar_change2'), - url(r'^change/(?P\d+).*/$', 'webinar.views.webinar_change'), + url(r'^change/(.*)/$', 'webinar.views.webinar_change'), url(r'^all/$', 'webinar.views.webinar_all'), ) diff --git a/webinar/views.py b/webinar/views.py index e26461e3..713d0fb7 100644 --- a/webinar/views.py +++ b/webinar/views.py @@ -60,64 +60,7 @@ def webinar_add(request): @login_required -def webinar_change(request, webinar_id): - """ - Return form of Webinar and fill it with existing Webinar object data. - - If form of webinar is posted redirect on the page of all webinars. - - """ - try: - #check if webinar_id exists else redirect to the list of webinars - webinar = Webinar.objects.get(id=webinar_id) - file_form = FileModelForm(initial={'model': 'webinar.Webinar'}) - except: - return HttpResponseRedirect('/webinar/all/') - if request.POST: - form = WebinarChangeForm(request.POST) - form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.all()] - if form.is_valid(): - form.save(webinar_id) - return HttpResponseRedirect('/webinar/all/') - else: - #fill form with data from database - data = {'web_page':webinar.web_page, 'data_begin':webinar.data_begin, 'currency':webinar.currency, - 'tax':webinar.tax, 'min_price':webinar.min_price, 'link':webinar.link, - 'max_price':webinar.max_price} - - data['theme'] = [item.id for item in webinar.theme.all()] - data['tag'] = [item.id for item in webinar.tag.all()] - #data from translated fields - for code, name in settings.LANGUAGES: - obj = Webinar._meta.translations_model.objects.get(language_code = code,master__id=webinar_id) #access to translated fields - data['name_%s' % code] = obj.name - data['programm_%s' % code] = obj.programm - data['main_title_%s' % code] = obj.main_title - data['discount_%s' % code] = obj.discount - data['title_%s' % code] = obj.title - data['keywords_%s' % code] = obj.keywords - data['descriptions_%s' % code] = obj.descriptions - #initial form - form = WebinarChangeForm(data) - form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.filter(theme__in=data['theme'])] - - args = {} - args.update(csrf(request)) - - args['form'] = form - args['languages'] = settings.LANGUAGES - args['file_form'] = file_form - - #get list of files which connected with specific model object - args['files'] = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(webinar), - object_id=getattr(webinar, 'id')) - args['obj_id'] = webinar_id - - return render_to_response('webinar_add.html', args) - - -@login_required -def webinar_change2(request, url): +def webinar_change(request, url): """ Return form of Webinar and fill it with existing Webinar object data. @@ -134,13 +77,13 @@ def webinar_change2(request, url): form = WebinarChangeForm(request.POST) form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.all()] if form.is_valid(): - form.save(getattr(webinar, id)) + form.save(getattr(webinar, 'id')) return HttpResponseRedirect('/webinar/all/') else: #fill form with data from database data = {'web_page':webinar.web_page, 'data_begin':webinar.data_begin, 'currency':webinar.currency, 'tax':webinar.tax, 'min_price':webinar.min_price, 'link':webinar.link, - 'max_price':webinar.max_price} + 'max_price':webinar.max_price, 'webinar_id':webinar.id} data['theme'] = [item.id for item in webinar.theme.all()] data['tag'] = [item.id for item in webinar.tag.all()]