diff --git a/.gitignore b/.gitignore index bd43984b..48f1c69c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,15 +4,16 @@ *~ *.egg-info *.doc +# jetbrains data .idea/ media/ media logs/ Thumbs.db -npm-debug.log /proj/local.py - +# gulp node_modules +npm-debug.log \ No newline at end of file diff --git a/article/admin.py b/article/admin.py index 55b05d7d..a2f12539 100644 --- a/article/admin.py +++ b/article/admin.py @@ -145,7 +145,7 @@ class BlogList(ListView): class BlogView(FormView): form_class = BlogForm - template_name = 'article/blog_form.html' + template_name = 'admin/article/blog_form.html' success_url = '/admin/article/blog/all/' obj = None diff --git a/conference/models.py b/conference/models.py index 067371db..8f067230 100644 --- a/conference/models.py +++ b/conference/models.py @@ -111,6 +111,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): keywords=models.CharField(max_length=250), ) + main = models.ForeignKey('expobanner.MainPage', blank=True, null=True, on_delete=models.SET_NULL) #fields saves information about creating and changing model created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) @@ -132,6 +133,13 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): return list(qs) #return list(Service.objects.language().filter(url__in=ids, type=Service.type.conference).order_by('sort')) + def get_services_detail(self): + excluded = ['tickets'] + country_ids = [item for item, bool in self.country.services if bool==True] + ids = [item for item, bool in self.services if bool==True] + qs = Service.objects.language().exclude(url__in=excluded).filter(Q(Q(url__in=country_ids) & Q(type=Service.type.conference)) | Q(url__in=ids)) + return list(qs) + def get_nearest_events(self): if self.theme.all(): theme = self.theme.all()[0] @@ -163,6 +171,9 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin): def get_visit_url(self): return '/conference-visit/%s/'%self.id + def get_note_url(self): + return '/conference/add-note/%s/'%self.url + def get_note_by_user(self, user_id): note = self.note.filter(user__id=user_id) try: diff --git a/expobanner/admin.py b/expobanner/admin.py index 4c053c53..30c528be 100644 --- a/expobanner/admin.py +++ b/expobanner/admin.py @@ -6,9 +6,9 @@ from django.shortcuts import get_object_or_404 from django.db.models import Sum from expobanner.models import URL, BannerGroup, Banner, Paid, MainPage, Top from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\ - PaidCreateForm, PaidUpdateForm, TopCreateForm, BannerLinkCreateForm, MainCreateForm, MainUpdateForm, TopUpdateForm + PaidCreateForm, PaidUpdateForm, TopCreateForm, BannerLinkCreateForm, MainCreateForm, MainConfCreateForm, MainUpdateForm, TopUpdateForm from exposition.models import Exposition - +from conference.models import Conference class BannersControl(TemplateView): template_name = 'admin/expobanner/banners_control.html' @@ -203,6 +203,8 @@ class PaidStat(DetailView): return context # ---------------------------------- + + class MainList(ListView): model = Exposition template_name = 'admin/expobanner/main_list.html' @@ -227,7 +229,6 @@ class MainUpdate(UpdateView): template_name = 'admin/expobanner/default_form.html' success_url = '/admin/expobanners/main/list/' - def get_context_data(self, **kwargs): context = super(MainUpdate, self).get_context_data(**kwargs) obj = self.object @@ -235,6 +236,50 @@ class MainUpdate(UpdateView): return context +class MainConfList(ListView): + model = Conference + template_name = 'admin/expobanner/main_list.html' + paginate_by = settings.ADMIN_PAGINATION + + def get_queryset(self): + qs = self.model.objects.language().filter(main__isnull=False).order_by('-main__public') + if self.request.GET.get('onlypublic'): + qs = qs.filter(main__public=True) + return qs + + def get_context_data(self, **kwargs): + context = super(MainConfList, self).get_context_data(**kwargs) + context.update({'conf': True}) + return context + + +from django.core.urlresolvers import reverse_lazy + + +class MainConfCreate(CreateView): + form_class = MainConfCreateForm + template_name = 'admin/expobanner/paid_create.html' + success_url = reverse_lazy('expobanner-conf-list_main') + + def get_context_data(self, **kwargs): + context = super(MainConfCreate, self).get_context_data(**kwargs) + context.update({'conf': True}) + return context + + +class MainConfUpdate(UpdateView): + model = MainPage + form_class = MainUpdateForm + template_name = 'admin/expobanner/default_form.html' + success_url = reverse_lazy('expobanner-conf-list_main') + + def get_context_data(self, **kwargs): + context = super(MainConfUpdate, self).get_context_data(**kwargs) + obj = self.object + context['conference'] = obj.get_event() + return context + + def main_turn(request, pk, status): main = get_object_or_404(MainPage, pk=pk) if status == 'on': @@ -242,10 +287,11 @@ def main_turn(request, pk, status): else: main.public = False main.save() - return HttpResponseRedirect('/admin/expobanners/main/list/') + return HttpResponseRedirect(request.META['HTTP_REFERER']) from datetime import datetime + class MainStat(DetailView): model = MainPage template_name = 'admin/expobanner/main_stat.html' diff --git a/expobanner/admin_urls.py b/expobanner/admin_urls.py index cce3e1aa..0c46fcd8 100644 --- a/expobanner/admin_urls.py +++ b/expobanner/admin_urls.py @@ -36,4 +36,10 @@ urlpatterns = patterns('expobanner.admin', url(r'^main/$', MainCreate.as_view(), name='expobanner-create_main'), url(r'^main/turn/(?P\d+)/(?P.*)/$', main_turn, name='expobanner-main-turn'), url(r'^main/(?P\d+)/stat/$', MainStat.as_view(), name='expobanner_stat_main'), + # conference on main page + url(r'^main/conf/list/$', MainConfList.as_view(), name='expobanner-conf-list_main'), + url(r'^main/conf/(?P\d+)/edit/$', MainConfUpdate.as_view(), name='expobanner-conf-update_main'), + url(r'^main/conf/$', MainConfCreate.as_view(), name='expobanner-conf-create_main'), + url(r'^main/conf/turn/(?P\d+)/(?P.*)/$', main_turn, name='expobanner-conf-main-turn'), + #url(r'^main/conf/(?P\d+)/stat/$', MainStat.as_view(), name='expobanner_stat_main'), ) \ No newline at end of file diff --git a/expobanner/forms.py b/expobanner/forms.py index 84d45965..a5a12179 100644 --- a/expobanner/forms.py +++ b/expobanner/forms.py @@ -2,6 +2,7 @@ from django import forms from expobanner.models import URL, BannerGroup, Banner, Paid, Top, MainPage from exposition.models import Exposition +from conference.models import Conference from country.models import Country from ckeditor.widgets import CKEditorWidget from theme.models import Theme, Tag @@ -107,6 +108,7 @@ class PaidCreateForm(forms.ModelForm): raise forms.ValidationError(u'Такой выставки не существует') return expo + class MainCreateForm(forms.ModelForm): verbose = u'Добавить выставку на главную' exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) @@ -137,6 +139,36 @@ class MainCreateForm(forms.ModelForm): return expo +class MainConfCreateForm(forms.ModelForm): + verbose = u'Добавить конференцию на главную' + conf = forms.CharField(label=u'Конференция', widget=forms.HiddenInput()) + + class Meta: + model = MainPage + fields = ['position', 'public'] + + def save(self, commit=True): + main = super(MainConfCreateForm, self).save(commit=False) + if commit: + conf = self.cleaned_data['conf'] + link = conf.get_permanent_url() + link_b = Banner.objects.create_for_paid(conf, link, 'main_page_link') + main.link = link_b + main.save() + + conf.main = main + conf.save() + return main + + def clean_conf(self): + conf_id = self.cleaned_data['conf'] + try: + conf = Conference.objects.get(id=conf_id) + except Conference.DoesNotExist: + raise forms.ValidationError(u'Такой конференции не существует') + return conf + + class PaidUpdateForm(forms.ModelForm): tickets = forms.URLField(label=u'Линк на билеты') participation = forms.URLField(label=u'Линк на участие') diff --git a/expobanner/models.py b/expobanner/models.py index 2208fc9a..8a1afabd 100644 --- a/expobanner/models.py +++ b/expobanner/models.py @@ -297,7 +297,13 @@ class MainPage(models.Model, StatMixin): try: return self.exposition_set.all()[0] except IndexError: - return None + try: + return self.conference_set.all()[0] + except IndexError: + return None + + def __unicode__(self): + return self.get_event().url def generatePassword(length=5): diff --git a/exposition/models.py b/exposition/models.py index 8a38e1a9..0ba5874a 100644 --- a/exposition/models.py +++ b/exposition/models.py @@ -178,6 +178,13 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): return list(qs) + def get_services_detail(self): + excluded = ['visit', 'tickets'] + country_ids = [item for item, bool in self.country.services if bool==True] + ids = [item for item, bool in self.services if bool==True] + qs = Service.objects.language().exclude(url__in=excluded).filter(Q(Q(url__in=country_ids) & Q(type=Service.type.expo)) | Q(url__in=ids)) + return list(qs) + def get_parent(self): return {} def get_absolute_url(self): @@ -285,6 +292,9 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): def get_visit_url(self): return '/exposition-visit/%s/'%self.id + def get_note_url(self): + return '/expo/add-note/%s/'%self.url + def get_timetables_days(self): tables = self.business_program.all() days = [] @@ -306,12 +316,6 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): def theme_ids(self): return [item['id'] for item in self.theme.all().values('id')] - def get_main_link(self): - if self.main: - return self.main.link.get_click_link() - else: - return self.get_permanent_url() - def get_top_link(self): if self.top: return self.top.link.get_click_link() diff --git a/functions/model_mixin.py b/functions/model_mixin.py index 5577ac9c..30b0a6de 100644 --- a/functions/model_mixin.py +++ b/functions/model_mixin.py @@ -5,11 +5,6 @@ from service.models import Service class ExpoMixin(object): - -# def get_index_text(self): -# names = [tr.name for tr in self.translations.all()] -# return names - def get_logo(self): logo = self.files.filter(purpose='logo') @@ -34,6 +29,12 @@ class EventMixin(object): url = '%s%s/'%(self.get_catalog_url(), self.url) return url + def get_main_link(self): + if self.main: + return self.main.link.get_click_link() + else: + return self.get_permanent_url() + def get_paid_catalog_url(self): return self.paid_new.catalog.get_click_link() @@ -45,12 +46,6 @@ class EventMixin(object): def get_logo(self): return self.logo - """ - logo = self.files.filter(purpose='logo') - if logo: - return logo[0] - return logo - """ def get_preview(self): diff --git a/functions/models_methods.py b/functions/models_methods.py index c5c45e58..943fac5b 100644 --- a/functions/models_methods.py +++ b/functions/models_methods.py @@ -39,6 +39,22 @@ class ExpoManager(TranslationManager): return result + def conf_main(self): + lang = translation.get_language() + key = 'conf_main_page_key_%s'%lang + result = cache.get(key) + if not result: + result = list(self.language(lang). + select_related('country', 'city', 'place', 'main'). + prefetch_related('tag'). + filter(main__isnull=False). + filter(main__public=True)) + cache.set(key, result, 50) + + return result + + + class CityManager(TranslationManager): diff --git a/proj/views.py b/proj/views.py index cfb06577..4746b611 100644 --- a/proj/views.py +++ b/proj/views.py @@ -1,22 +1,18 @@ # -*- coding: utf-8 -*- -from django.core.context_processors import csrf from django.shortcuts import render_to_response from django.template import RequestContext from django.views.generic import TemplateView from django.conf import settings -from exposition.models import Exposition -from theme.models import Theme -from news.models import News -from article.models import Article -from functions.cache_mixin import JitterCacheMixin, CacheMixin - -from functions.forms import ThemeSearch, PlaceSearch - -from functions.search_forms import EventSearchForm, ExpositionSearchForm -from functions.custom_views import ExpoListView +from django.utils.translation import get_language +from functions.cache_mixin import JitterCacheMixin +from functions.forms import ThemeSearch +from functions.search_forms import ExpositionSearchForm from accounts.forms import RegistrationCompleteForm, SocialRegistrationCompleteForm from meta.models import SeoText -from django.utils.translation import get_language +from theme.models import Theme +from article.models import Article +from exposition.models import Exposition +from conference.models import Conference def clear_slashes(str_): @@ -73,11 +69,13 @@ def error404(request): class MainPageView(JitterCacheMixin, TemplateView): cache_range = settings.CACHE_RANGE - template_name = 'index.html' + template_name = 'client/index.html' def get_context_data(self, **kwargs): context = super(MainPageView, self).get_context_data(**kwargs) - ev = Exposition.objects.expo_main() + ex = Exposition.objects.expo_main() + conf = Conference.objects.conf_main() + ev = ex + conf events = sorted(ev, key=lambda x: x.main.position) # update main_page counter for event in events: diff --git a/service/admin.py b/service/admin.py index 16bb9707..752890b4 100644 --- a/service/admin.py +++ b/service/admin.py @@ -117,34 +117,6 @@ def get_city(request): return HttpResponse('error') -class ServiceControlList(ListView): - model = Service - template_name = 'admin/service/control_list.html' - paginate_by = 20 - -from django.views.generic.detail import SingleObjectMixin -from django.views.generic.edit import FormMixin -from django.views.generic import DetailView -from service.forms import ServiceControlForm -class ServiceControl(FormMixin, DetailView): - form_class = ServiceControlForm - template_name = 'admin/service/control.html' - model = Service - - - def get_form(self, form_class): - obj = self.object - data = obj.get_current_state() - - return form_class(data) - - def get_context_data(self, **kwargs): - context = super(ServiceControl, self).get_context_data(**kwargs) - context['form'] = self.get_form(self.form_class) - return context - - - from django.shortcuts import get_object_or_404 from django.views.generic import UpdateView, ListView, DeleteView from .forms import LinkedServiceForm @@ -157,7 +129,7 @@ class LinkedServiceUpdateView(UpdateView): form_class = LinkedServiceForm model = LinkedService template_name = "admin/service/linked_service.html" - success_url = "/admin/service/test/all/" + success_url = "/admin/service/control/all/" def get_object(self, queryset=None): url = self.kwargs['url'] diff --git a/service/admin_urls.py b/service/admin_urls.py index f1816405..a4744e78 100644 --- a/service/admin_urls.py +++ b/service/admin_urls.py @@ -2,11 +2,9 @@ from django.conf.urls import patterns, include, url from views import CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \ ParticipationListView, RemoteListView,TicketsListView -from service.admin import ServiceControlList, ServiceControl, LinkedServiceList, LinkedServiceUpdateView, LinkedServiceDeleteView +from service.admin import LinkedServiceList, LinkedServiceUpdateView, LinkedServiceDeleteView urlpatterns = patterns('service.admin', - url(r'^control/list/$', ServiceControlList.as_view()), - url(r'^control/(?P.*)/$', ServiceControl.as_view()), url(r'^add.*/$', 'service_add'), url(r'^delete/(?P.*)/$', 'service_delete'), url(r'^change/(?P.*)/$', 'service_change'), @@ -18,14 +16,11 @@ urlpatterns = patterns('service.admin', url(r'order/participation/$', ParticipationListView.as_view()), url(r'order/remote/$', RemoteListView.as_view()), url(r'order/tickets/$', TicketsListView.as_view()), - url('^test/delete/(?P[a-z]*)/', LinkedServiceDeleteView.as_view(), name='linked_service_delete'), - url('^test/all/', LinkedServiceList.as_view(), name = 'linked_service_all'), - url('^test/(?P[a-z]*)/', LinkedServiceUpdateView.as_view(), name= 'linked_service_update'), - + url(r'^control/delete/(?P[a-z]*)/', LinkedServiceDeleteView.as_view(), name='linked_service_delete'), + url(r'^control/all/', LinkedServiceList.as_view(), name='linked_service_all'), + url(r'^control/(?P[a-z]*)/', LinkedServiceUpdateView.as_view(), name='linked_service_update'), #ajax url(r'^get_city/$', 'get_city'), -#url(r'^get_country/$', 'get_country'), - ) diff --git a/service/forms.py b/service/forms.py index 011e6a1c..a6c6192c 100644 --- a/service/forms.py +++ b/service/forms.py @@ -128,35 +128,16 @@ from country.models import Area, Country from exposition.models import Exposition from conference.models import Conference -class ServiceControlForm(forms.Form): - event = [{'verbose': 'Выставки', 'model': Exposition, 'id': 1, 'service_bit': 'expo'}, - {'verbose': 'Конференции', 'model': Conference, 'id': 2, 'service_bit': 'conference'}] - region = forms.ChoiceField(required=False, label='Регион', - choices=[('', '')]+[(item.id, item.name) - for item in list(Area.objects.all())]) - country = forms.MultipleChoiceField(required=False, label='Страны', - choices=[('', '')]+[(item.id, item.name) - for item in list(Country.objects.all())]) - country_all = forms.BooleanField(required=False) - expositions = forms.CharField(label=u'Выставки', widget=forms.HiddenInput(), required=False) - conferences = forms.CharField(label=u'Конференции', widget=forms.HiddenInput(), required=False) - - def __init__(self, *args, **kwargs): - super(ServiceControlForm, self).__init__(*args, **kwargs) - self.fields['event_type'] = forms.MultipleChoiceField(required=False, label = 'Тип события', - widget=forms.CheckboxSelectMultiple(), - choices=[(item['service_bit'], item['verbose']) - for item in self.event]) - from .models import LinkedService from django.db.models.query import EmptyQuerySet class LinkedServiceForm(forms.ModelForm): - type = forms.MultipleChoiceField(choices = [(x, x) for x in list(Service.type)], widget = forms.CheckboxSelectMultiple, required=False) - expositions = forms.CharField(widget=forms.HiddenInput,required=False) - conferences = forms.CharField(widget=forms.HiddenInput, required=False) + type = forms.MultipleChoiceField(label='Тип', choices = [(x, x) for x in list(Service.type)], widget = forms.CheckboxSelectMultiple, required=False) + expositions = forms.CharField(label='Выставки', widget=forms.HiddenInput,required=False) + conferences = forms.CharField(label='Конференции', widget=forms.HiddenInput, required=False) + countries = forms.MultipleChoiceField(label='Страны', choices=[(c.id, c.name) for c in list(set(Country.objects.language()))]) class Meta: model = LinkedService @@ -166,7 +147,7 @@ class LinkedServiceForm(forms.ModelForm): } def clean_countries(self): - countries = Country.objects.language().filter(id__in=self.cleaned_data['countries']) + countries = Country.objects.language().filter(id__in=self.cleaned_data['countries']) return countries def clean_expositions(self): diff --git a/service/models.py b/service/models.py index 4549f10e..f39824d7 100644 --- a/service/models.py +++ b/service/models.py @@ -47,60 +47,6 @@ class Service(TranslatableModel): def get_price(self): pr = self.price - def get_current_state(self): - """ - uses for control form - :return: - """ - from country.models import Country - country_all = False - country = [] - region = [] - expositions = [] - conferences = [] - service = self.url - event_type = [key for key, value in self.type.iteritems() if value] - if not event_type: - return {'event_type': event_type, - 'region': region, - 'country': country, - 'country_all': country_all, - 'expositions': expositions, - 'conferences': conferences} - - count1 = Country.objects.filter().count() - count2 = Country.objects.filter(services=getattr(Country.services, service)).count() - country_all = count1 == count2 - if not country_all: - from exposition.models import Exposition - from conference.models import Conference - from country.models import Area - from django.utils.translation import get_language - lang = get_language() - - countries = list(Country.objects.language(lang).filter(services=getattr(Country.services, service))) - - expositions = [(item.id, item.name) for item in Exposition.enable.upcoming().exclude(country__in=countries, services=getattr(Exposition.services, service))] - conferences = [(item.id, item.name) for item in Conference.enable.upcoming().exclude(country__in=countries, services=getattr(Conference.services, service))] - - region = [] - countries = set(countries) - for item in list(Area.objects.language(lang).all()): - print(item) - area_countries = item.countries() - if set(area_countries).issubset(countries): - region.append((item.id, item.name)) - countries = countries - set(area_countries) - - country = [(item.id, item.name) for item in list(countries)] - - state = {'event_type': event_type, - 'region': region, - 'country': country, - 'country_all': country_all, - 'expositions': expositions, - 'conferences': conferences} - return state from django.db.models.signals import post_save from functions.signal_handlers import post_save_handler @@ -238,5 +184,14 @@ class LinkedService(models.Model): self.update_expositions_flag() self.update_conferences_flag() + def countries_count(self): + if not self.exclude_countries: + return self.countries.all().count() + else: + from country.models import Country + all = Country.objects.filter().count() + excluded = self.countries.all().count() + return all - excluded + def __unicode__(self): return u'Linked service for %s'%self.service.url diff --git a/templates/admin/article/blog_form.html b/templates/admin/article/blog_form.html index 521110e1..1b41a403 100644 --- a/templates/admin/article/blog_form.html +++ b/templates/admin/article/blog_form.html @@ -54,7 +54,7 @@ {% if not article %}
- +
{{ form.slug }} {{ form.slug.errors }} diff --git a/templates/admin/expobanner/default_form.html b/templates/admin/expobanner/default_form.html index 3322088e..46a441d9 100644 --- a/templates/admin/expobanner/default_form.html +++ b/templates/admin/expobanner/default_form.html @@ -51,7 +51,7 @@
-

{{ form.verbose }}

+

{% if form.verbose %} {{ form.verbose }} {% else %} {{ object.get_event }} {% endif %}

{% for field in form %} diff --git a/templates/admin/expobanner/main_list.html b/templates/admin/expobanner/main_list.html index a06a2411..2af62ce8 100644 --- a/templates/admin/expobanner/main_list.html +++ b/templates/admin/expobanner/main_list.html @@ -4,13 +4,17 @@
-

Список выставок на главной

+

Список {% if conf %}конференций{% else %}выставок{% endif %} на главной

{% block list_table %} + {% endif %} +
Только опубликование @@ -19,7 +23,11 @@ - + {% if conf %} + + {% else %} + + {% endif %} @@ -31,8 +39,13 @@ - - + {% if conf %} + + + {% else %} + + + {% endif %} {% endfor %} diff --git a/templates/admin/expobanner/paid_create.html b/templates/admin/expobanner/paid_create.html index 4e3af395..ede4d3da 100644 --- a/templates/admin/expobanner/paid_create.html +++ b/templates/admin/expobanner/paid_create.html @@ -39,6 +39,39 @@ } }); + + $('#id_conf').select2({ + placeholder: 'Найти', + width: 'element', + ajax: { + url: '/admin/conference/search/', + dataType: "json", + quietMillis: 200, + multiple: true, + + data: function(term, page){ + return {term: term, + page: page}; + }, + + results: function (data) { + var results = []; + $.each(data, function(index, item){ + results.push({ + id: item.id, + text: item.label + }); + }); + return {results: results}; + } + }, + initSelection : function(element, callback) { + var id= $(element).val(); + var text = $(element).attr('data-init-text'); + callback({id: id, text:text}); + + } + }); }); {% endblock %} diff --git a/templates/admin/includes/admin_nav.html b/templates/admin/includes/admin_nav.html index 5d9c9ced..c89e71e1 100644 --- a/templates/admin/includes/admin_nav.html +++ b/templates/admin/includes/admin_nav.html @@ -43,6 +43,7 @@
  • Тематики для блогов
  • Теги
  • Услуги
  • +
  • Управление услугами
  • Главная страница
  • Мета
  • @@ -107,6 +108,7 @@
  • Платные выставки
  • Выставки в топе
  • Выставки на главной
  • +
  • Конференции на главной
  • diff --git a/templates/admin/service/control_list.html b/templates/admin/service/control_list.html deleted file mode 100644 index 38bf41b8..00000000 --- a/templates/admin/service/control_list.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends 'admin_list.html' %} - -{% block body %} -
    -
    -

    Список услуг

    -
    -
    - -
    ВыставкаКонференцияВыставкаПозиция    
    {{ item }} {{ item.main.position }}Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Статистика
    - - - - - - - - - {% for item in object_list %} - - - - - - - - - {% endfor %} - -
    idНазвание 
    {{ item.id }}{{ item.name }} - - Управлять - -
    -
    - {# pagination #} - {% include 'admin/includes/admin_pagination.html' with page_obj=object_list %} -
    -{% endblock %} \ No newline at end of file diff --git a/templates/admin/service/linked_service.html b/templates/admin/service/linked_service.html index fd007a7c..ac734e4d 100644 --- a/templates/admin/service/linked_service.html +++ b/templates/admin/service/linked_service.html @@ -15,6 +15,7 @@ - @@ -15,25 +14,27 @@ {% block body %} - {% csrf_token %}{{ form.errors }} + {% csrf_token %}
    - {% if object %} Изменить {% else %} Добавить {% endif %}тему + {% if theme_id %} Изменить {% else %} Добавить {% endif %}тему

    Информация

    - {% for field in form %} - - - - {% endfor %} + {# name #} + {% with field='name' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + + {# main_title #} + {% with field='main_title' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# description #} + {% with field='description' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %}
    diff --git a/templates/client/includes/conference/conference_services.html b/templates/client/includes/conference/conference_services.html index 829bfd97..b98f4d71 100644 --- a/templates/client/includes/conference/conference_services.html +++ b/templates/client/includes/conference/conference_services.html @@ -2,13 +2,12 @@
    \ No newline at end of file diff --git a/templates/client/includes/exposition/exposition_services.html b/templates/client/includes/exposition/exposition_services.html index 5e9b936f..b98f4d71 100644 --- a/templates/client/includes/exposition/exposition_services.html +++ b/templates/client/includes/exposition/exposition_services.html @@ -2,15 +2,12 @@
    \ No newline at end of file diff --git a/templates/client/includes/index/main_events.html b/templates/client/includes/index/main_events.html index 17368ba8..6fa3c0ca 100644 --- a/templates/client/includes/index/main_events.html +++ b/templates/client/includes/index/main_events.html @@ -36,7 +36,7 @@
    {% if event|in_calendar:request.user %}{% trans 'Убрать из календаря' %}{% else %}{% trans 'добавить в календарь' %}{% endif %}
    - {% trans 'заметка' %} + {% trans 'заметка' %}
    diff --git a/templates/client/package.json b/templates/client/package.json new file mode 100644 index 00000000..aab78596 --- /dev/null +++ b/templates/client/package.json @@ -0,0 +1,30 @@ +{ + "name": "kotzilla", + "version": "0.0.0", + "description": "", + "main": "gulpfile.js", + "dependencies": { + "gulp": "~3.9.0" + }, + "devDependencies": { + "connect": "~3.4.0", + "gulp-concat": "~2.6.0", + "gulp-livereload": "~3.8.1", + "gulp": "~3.9.0", + "gulp-stylus": "~2.1.0", + "gulp-uglify": "~1.4.1", + "gulp-jade": "~1.1.0", + "gulp-imagemin": "~2.3.0", + "gulp-csso": "~1.0.0", + "gulp-myth": "~1.0.3", + "gulp-rename": "~1.2.2", + "gulp-autoprefixer": "~3.0.2", + "gulp-cssmin": "~0.1.7", + "gulp-newer": "~0.5.1" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "BSD-2-Clause" +} diff --git a/templates/client/service/participation.html b/templates/client/service/participation.html index 864c5179..d6e5efc3 100644 --- a/templates/client/service/participation.html +++ b/templates/client/service/participation.html @@ -55,7 +55,7 @@
    - {% csrf_token %} + {% csrf_token %}
    diff --git a/templates/client/service/remotely.html b/templates/client/service/remotely.html index 65a7787d..1a7e3a42 100644 --- a/templates/client/service/remotely.html +++ b/templates/client/service/remotely.html @@ -58,7 +58,7 @@
    - {% csrf_token %} + {% csrf_token %}
    diff --git a/templates/client/service/tickets.html b/templates/client/service/tickets.html index 94f2b6c3..63372e45 100644 --- a/templates/client/service/tickets.html +++ b/templates/client/service/tickets.html @@ -51,7 +51,7 @@
    - {% csrf_token %} + {% csrf_token %}
    diff --git a/templates/client/service/tour.html b/templates/client/service/tour.html index 8a58e0b0..393a0e77 100644 --- a/templates/client/service/tour.html +++ b/templates/client/service/tour.html @@ -53,7 +53,7 @@
    - {% csrf_token %} + {% csrf_token %}
    diff --git a/templates/client/service/translator.html b/templates/client/service/translator.html index adcb4285..c0236e37 100644 --- a/templates/client/service/translator.html +++ b/templates/client/service/translator.html @@ -51,7 +51,7 @@
    {% comment %}{{ form.errors }}{% endcomment %} - {% csrf_token %} + {% csrf_token %}
    diff --git a/templates/client/static_client/css/vendor.css b/templates/client/static_client/css/vendor.css index 2daa3034..64743fb6 100644 --- a/templates/client/static_client/css/vendor.css +++ b/templates/client/static_client/css/vendor.css @@ -2809,4 +2809,3 @@ html[dir="rtl"] .select2-container-multi .select2-choices li height: 100px; overflow: scroll; } - diff --git a/templates/client/static_client/js/_modules/block.common.js b/templates/client/static_client/js/_modules/block.common.js index 7c1becea..c8f0f3c7 100644 --- a/templates/client/static_client/js/_modules/block.common.js +++ b/templates/client/static_client/js/_modules/block.common.js @@ -93,7 +93,12 @@ if (EXPO.common){ $.fancybox.close(true); $.fancybox('#'+EXPO.common.opt.successRegisterId); }else{ - + if($(self.DOM).attr('id') == 'log_form'){ + dataLayer.push({'event': 'logform'}); + } + if($(self.DOM).attr('id') == 'end-reg-form'){ + dataLayer.push({'event': 'endregform'}); + } window.location.reload(); } }else{ diff --git a/templates/client/static_client/js_min/_modules/block.common.min.js b/templates/client/static_client/js_min/_modules/block.common.min.js index 338162e4..e348fbda 100644 --- a/templates/client/static_client/js_min/_modules/block.common.min.js +++ b/templates/client/static_client/js_min/_modules/block.common.min.js @@ -1 +1 @@ -var EXPO=EXPO||{};EXPO.common?console.warn("WARNING: EXPO.common is already defined!"):EXPO.common=function(){var e,t={},s=function(e,t){return(e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector).call(e,t)};t.opt={};var r=function(e){this.fields=[],this.allIsClear=!1,this.ajaxUrl=e.getAttribute("action"),this.DOM=e,this._initFields(),this._eventController()};return r.prototype={_eventController:function(){var e=this;this.DOM.addEventListener?this.DOM.addEventListener("submit",function(t){return e.validate(),t.preventDefault(),!1},!1):this.DOM.attachEvent&&this.DOM.attachEvent("onsubmit",function(t){return e.validate(),t.preventDefault(),!1})},_initFields:function(){},validate:function(){var t,s=this,r=$(s.DOM).serialize(),a={},o="err-message-box",i=s.DOM.querySelector("."+o),n=i.innerHTML,l=function(r){var o,l;if(t=r,s.unHighlightFields(),t.success)i&&EXPO.common.removeClass(i,"active"),$(s.DOM).attr("id")==EXPO.common.opt.registerFormId?(o=$("#"+EXPO.common.opt.successRegisterId),l=$.trim($("#id_email",s.DOM).val()),$("."+EXPO.common.opt.resendLetterClass,o).attr("data-email",l),$.fancybox.close(!0),$.fancybox("#"+EXPO.common.opt.successRegisterId)):window.location.reload();else{EXPO.common.removeClass(i,"active"),a={},s.fields=[];for(var c in t.errors)t.errors.hasOwnProperty(c)&&("__all__"!=c?(a={name:c,id:"id_"+c,errorText:t.errors[c]},s.fields.push(a)):i&&(EXPO.common.addClass(i,"active"),n.indexOf(t.errors[c])<0&&i.insertAdjacentHTML("beforeend",t.errors[c]+" ")));s.highliteFields()}e.hide()};s.unHighlightFields(),e.show(),EXPO.common.postRequest(r,s.ajaxUrl,l)},highliteFields:function(){for(var e,t,s=0;s").attr("class","error").append(s);r.parent().addClass("required err").prepend(a)}))};"post"==o?$.post(s,a,i):$.get(s,a,i)}),$("form.simple-validate-register").on("submit",function(e){e.preventDefault();var t=$(this),s=t.attr("action"),r=$(this).serialize(),a=t.attr("method"),o=$("#pw-reg-complete"),i=$(".resend-letter",o),n=$.trim($("#id_email",t).val()),l=function(e){e.success?(dataLayer.push({event:"regform"}),$(".error",t).remove(),$(".required.err",t).removeClass("required err"),$("input:text",t).val(""),$(".pwf-line .msg-help",t).each(function(){var e=$(this),t=e.attr("data-default");""!=$.trim(t)&&e.html("").text(t)}),i.attr("data-email",n),$.fancybox.close(!0),$.fancybox("#pw-reg-complete")):($(".error",t).remove(),$(".required.err",t).removeClass("required err"),$(".pwf-line .msg-help",t).each(function(){var e=$(this),t=e.attr("data-default");""!=$.trim(t)&&e.html("").text(t)}),$.each(e.errors,function(e,s){var r=$("#id_"+e,t),a=$("
    ").attr("class","error").append(s),o=r.closest(".pwf-line").find(".msg-help");r.parent().addClass("required err"),o.attr("data-default",o.text()),o.text("").prepend(a)}))};"post"==a?$.post(s,r,l):$.get(s,r,l)})}),$(function(){$.fancybox.helpers.overlay.overlay=$('
    ').appendTo("body"),$.fn.customRadioCheck=function(){return $(this).each(function(){function e(){if("radio"==s){var e=t.attr("name"),r=$('input[type="radio"]').filter('[name="'+e+'"]');r.each(function(){var e=$(this).closest(".custom-radio");e.removeClass("checked"),$(this).is(":checked")&&e.addClass("checked")})}else t.prop("checked")?a.addClass("checked"):a.removeClass("checked");t.trigger("blur")}var t=$(this),s=t.attr("type"),r=t.closest("label"),a=t.wrap("").parent();r.addClass("custom-radio-check"),e(),t.on("change",e)})},$("input[type='checkbox'], input[type='radio']").customRadioCheck()}),function(e){e.fn.inlineStyle=function(t){var s,r=this.attr("style");return r&&r.split(";").forEach(function(r){var a=r.split(":");e.trim(a[0])===t&&(s=a[1])}),s}}(jQuery),t.init=function(t){$.extend(this.opt,t);var s,r=this,a=this.opt.addCalendarClass,o=this.opt.removeCalendarClass,i=this.opt.addCalendarText,n=this.opt.removeCalendarText,l=r.opt.staticValidation.errorClass,c=r.opt.staticValidation.containerClass;r.opt.staticValidation.blobClass;$(function(){s=$("."+l),e=$("#wait-ajax:not(.absolute)").css({"z-index":"8031"}),$("body").on("click","."+a+", ."+o,function(e){i=r.opt.addCalendarText,n=r.opt.removeCalendarText,e.preventDefault();var t=$(this),s=t.attr("href");$.get(s,function(e){e.not_authorized?$.fancybox.open("#"+r.opt.loginModalId):e.success&&(e["in"]?t.removeClass(a).addClass(o).text(n):t.removeClass(o).addClass(a).text(i))})}),s.length&&s.find("input:text").on("keyup",function(){""!=$.trim($(this).val())?$(this).closest("."+l).removeClass(l):$(this).closest("."+c).addClass(l)});for(var t=0;t=0;)r=r.replace(" "+s+" "," ");e.className=r.replace(/^\s+|\s+$/g," ")}return e},t.closest=function(e,s){for(var r=function(s){return t.hasClass(e,s)};e;){if(r(s))return e;e=e.parentNode}},t.children=function(e,t){for(var r,a=[],r=0,o=e.childNodes.length;o>r;++r)s(e.childNodes[r],t)&&a.push(e.childNodes[r]);return a},t.postRequest=function(e,t,s){e||(e=""),$.ajax({type:"POST",url:t,data:e,success:function(e){return"function"!=typeof s?e:(console.log("data recieved:"),console.log(e),console.log(JSON.stringify(e)),s(e),void 0)}})},t.getRequest=function(e,t,s){e||(e=""),$.ajax({type:"GET",url:t,data:e,success:function(e){return"function"!=typeof s?e:(console.log("data recieved:"),console.log(e),console.log(JSON.stringify(e)),s(e),void 0)}})},t.Modal=function(e){var t=this;this.id,this.opt=e,this.DOMwrap=document.getElementById(e.id),this.DOM=this.DOMwrap.querySelector("."+e.wrapClass),$(".modal-close",this.DOM).on("click",function(){t.close()}),$(".modals > *").on("click",function(e){$(e.target.parentNode).find(t.DOMwrap).length&&t.close()})},t.Modal.prototype={pullData:function(e){this.id=e.substr(1),$(e).show().siblings().hide(),this.refresh()},open:function(){$(this.DOMwrap).fadeIn(),t.addClass(document.body,"ov-hidden")},close:function(){$(this.DOMwrap).fadeOut(),t.removeClass(document.body,"ov-hidden")},refresh:function(){var e=this;e.DOM.style.width=e.opt.size[e.id].width+"px",e.DOM.style.minHeight=e.opt.size[e.id].height+"px",e.DOM.style.marginLeft=-(e.opt.size[e.id].width/2)+"px",e.DOM.style.marginTop=-(e.opt.size[e.id].height/2)+"px"}},t.SEOhide={seoContent:{},seoHrefs:{},decode:function(e){for(var t=$("["+e+"]"),s=0,r=t.length;r>s;s++){var a=t.eq(s),o=a.attr("data-hash");switch(a.data("type")){case"href":a.attr("href",Base64.decode(this.seoHrefs[o]));break;case"content":a.replaceWith(Base64.decode(this.seoContent[o]))}}}},t.nl2br=function(e,t){var s=t||"undefined"==typeof t?"
    ":"
    ";return(e+"").replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g,"$1"+s+"$2")},t}(); \ No newline at end of file +var EXPO=EXPO||{};EXPO.common?console.warn("WARNING: EXPO.common is already defined!"):EXPO.common=function(){var e,t={},r=function(e,t){return(e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.oMatchesSelector).call(e,t)};t.opt={};var s=function(e){this.fields=[],this.allIsClear=!1,this.ajaxUrl=e.getAttribute("action"),this.DOM=e,this._initFields(),this._eventController()};return s.prototype={_eventController:function(){var e=this;this.DOM.addEventListener?this.DOM.addEventListener("submit",function(t){return e.validate(),t.preventDefault(),!1},!1):this.DOM.attachEvent&&this.DOM.attachEvent("onsubmit",function(t){return e.validate(),t.preventDefault(),!1})},_initFields:function(){},validate:function(){var t,r=this,s=$(r.DOM).serialize(),a={},o="err-message-box",i=r.DOM.querySelector("."+o),n=i.innerHTML,l=function(s){var o,l;if(t=s,r.unHighlightFields(),t.success)i&&EXPO.common.removeClass(i,"active"),$(r.DOM).attr("id")==EXPO.common.opt.registerFormId?(o=$("#"+EXPO.common.opt.successRegisterId),l=$.trim($("#id_email",r.DOM).val()),$("."+EXPO.common.opt.resendLetterClass,o).attr("data-email",l),$.fancybox.close(!0),$.fancybox("#"+EXPO.common.opt.successRegisterId)):("log_form"==$(r.DOM).attr("id")&&dataLayer.push({event:"logform"}),"end-reg-form"==$(r.DOM).attr("id")&&dataLayer.push({event:"endregform"}),window.location.reload());else{EXPO.common.removeClass(i,"active"),a={},r.fields=[];for(var c in t.errors)t.errors.hasOwnProperty(c)&&("__all__"!=c?(a={name:c,id:"id_"+c,errorText:t.errors[c]},r.fields.push(a)):i&&(EXPO.common.addClass(i,"active"),n.indexOf(t.errors[c])<0&&i.insertAdjacentHTML("beforeend",t.errors[c]+" ")));r.highliteFields()}e.hide()};r.unHighlightFields(),e.show(),EXPO.common.postRequest(s,r.ajaxUrl,l)},highliteFields:function(){for(var e,t,r=0;r").attr("class","error").append(r);s.parent().addClass("required err").prepend(a)}))};"post"==o?$.post(r,a,i):$.get(r,a,i)}),$("form.simple-validate-register").on("submit",function(e){e.preventDefault();var t=$(this),r=t.attr("action"),s=$(this).serialize(),a=t.attr("method"),o=$("#pw-reg-complete"),i=$(".resend-letter",o),n=$.trim($("#id_email",t).val()),l=function(e){e.success?(dataLayer.push({event:"regform"}),$(".error",t).remove(),$(".required.err",t).removeClass("required err"),$("input:text",t).val(""),$(".pwf-line .msg-help",t).each(function(){var e=$(this),t=e.attr("data-default");""!=$.trim(t)&&e.html("").text(t)}),i.attr("data-email",n),$.fancybox.close(!0),$.fancybox("#pw-reg-complete")):($(".error",t).remove(),$(".required.err",t).removeClass("required err"),$(".pwf-line .msg-help",t).each(function(){var e=$(this),t=e.attr("data-default");""!=$.trim(t)&&e.html("").text(t)}),$.each(e.errors,function(e,r){var s=$("#id_"+e,t),a=$("
    ").attr("class","error").append(r),o=s.closest(".pwf-line").find(".msg-help");s.parent().addClass("required err"),o.attr("data-default",o.text()),o.text("").prepend(a)}))};"post"==a?$.post(r,s,l):$.get(r,s,l)})}),$(function(){$.fancybox.helpers.overlay.overlay=$('
    ').appendTo("body"),$.fn.customRadioCheck=function(){return $(this).each(function(){function e(){if("radio"==r){var e=t.attr("name"),s=$('input[type="radio"]').filter('[name="'+e+'"]');s.each(function(){var e=$(this).closest(".custom-radio");e.removeClass("checked"),$(this).is(":checked")&&e.addClass("checked")})}else t.prop("checked")?a.addClass("checked"):a.removeClass("checked");t.trigger("blur")}var t=$(this),r=t.attr("type"),s=t.closest("label"),a=t.wrap("").parent();s.addClass("custom-radio-check"),e(),t.on("change",e)})},$("input[type='checkbox'], input[type='radio']").customRadioCheck()}),function(e){e.fn.inlineStyle=function(t){var r,s=this.attr("style");return s&&s.split(";").forEach(function(s){var a=s.split(":");e.trim(a[0])===t&&(r=a[1])}),r}}(jQuery),t.init=function(t){$.extend(this.opt,t);var r,s=this,a=this.opt.addCalendarClass,o=this.opt.removeCalendarClass,i=this.opt.addCalendarText,n=this.opt.removeCalendarText,l=s.opt.staticValidation.errorClass,c=s.opt.staticValidation.containerClass;s.opt.staticValidation.blobClass;$(function(){r=$("."+l),e=$("#wait-ajax:not(.absolute)").css({"z-index":"8031"}),$("body").on("click","."+a+", ."+o,function(e){i=s.opt.addCalendarText,n=s.opt.removeCalendarText,e.preventDefault();var t=$(this),r=t.attr("href");$.get(r,function(e){e.not_authorized?$.fancybox.open("#"+s.opt.loginModalId):e.success&&(e["in"]?t.removeClass(a).addClass(o).text(n):t.removeClass(o).addClass(a).text(i))})}),r.length&&r.find("input:text").on("keyup",function(){""!=$.trim($(this).val())?$(this).closest("."+l).removeClass(l):$(this).closest("."+c).addClass(l)});for(var t=0;t=0;)s=s.replace(" "+r+" "," ");e.className=s.replace(/^\s+|\s+$/g," ")}return e},t.closest=function(e,r){for(var s=function(r){return t.hasClass(e,r)};e;){if(s(r))return e;e=e.parentNode}},t.children=function(e,t){for(var s,a=[],s=0,o=e.childNodes.length;o>s;++s)r(e.childNodes[s],t)&&a.push(e.childNodes[s]);return a},t.postRequest=function(e,t,r){e||(e=""),$.ajax({type:"POST",url:t,data:e,success:function(e){return"function"!=typeof r?e:(console.log("data recieved:"),console.log(e),console.log(JSON.stringify(e)),r(e),void 0)}})},t.getRequest=function(e,t,r){e||(e=""),$.ajax({type:"GET",url:t,data:e,success:function(e){return"function"!=typeof r?e:(console.log("data recieved:"),console.log(e),console.log(JSON.stringify(e)),r(e),void 0)}})},t.Modal=function(e){var t=this;this.id,this.opt=e,this.DOMwrap=document.getElementById(e.id),this.DOM=this.DOMwrap.querySelector("."+e.wrapClass),$(".modal-close",this.DOM).on("click",function(){t.close()}),$(".modals > *").on("click",function(e){$(e.target.parentNode).find(t.DOMwrap).length&&t.close()})},t.Modal.prototype={pullData:function(e){this.id=e.substr(1),$(e).show().siblings().hide(),this.refresh()},open:function(){$(this.DOMwrap).fadeIn(),t.addClass(document.body,"ov-hidden")},close:function(){$(this.DOMwrap).fadeOut(),t.removeClass(document.body,"ov-hidden")},refresh:function(){var e=this;e.DOM.style.width=e.opt.size[e.id].width+"px",e.DOM.style.minHeight=e.opt.size[e.id].height+"px",e.DOM.style.marginLeft=-(e.opt.size[e.id].width/2)+"px",e.DOM.style.marginTop=-(e.opt.size[e.id].height/2)+"px"}},t.SEOhide={seoContent:{},seoHrefs:{},decode:function(e){for(var t=$("["+e+"]"),r=0,s=t.length;s>r;r++){var a=t.eq(r),o=a.attr("data-hash");switch(a.data("type")){case"href":a.attr("href",Base64.decode(this.seoHrefs[o]));break;case"content":a.replaceWith(Base64.decode(this.seoContent[o]))}}}},t.nl2br=function(e,t){var r=t||"undefined"==typeof t?"
    ":"
    ";return(e+"").replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g,"$1"+r+"$2")},t}(); \ No newline at end of file diff --git a/theme/admin.py b/theme/admin.py index 8914587f..d2288161 100644 --- a/theme/admin.py +++ b/theme/admin.py @@ -182,13 +182,46 @@ class ThemeBlogListView(ListView): paginate_by = settings.ADMIN_PAGINATION -class ThemeBlogCreateView(CreateView): - template_name = "admin/theme/theme_blog_new.html" +class ThemeBlogDeleteView(DeleteView): + template_name = "admin/theme/theme_blog_confirm_delete.html" model = ThemeBlog - form_class = ThemeBlogForm success_url = reverse_lazy("theme_blog_all") + pk_url_kwarg = "theme_id" + +def blog_theme_add(request): + return add_object(request, ThemeBlogForm, 'theme_blog_new.html', reverse_lazy("theme_blog_all")) +@login_required +def blog_theme_change(request, theme_id=None): + try: + theme = ThemeBlog.objects.get(id=theme_id) + except: + return HttpResponseRedirect('theme_blog_all') + if request.POST: + form = ThemeBlogForm(request.POST) + if form.is_valid(): + form.save(theme_id) + return HttpResponseRedirect(reverse_lazy("theme_blog_all")) + else: + data = {} + for code, name in settings.LANGUAGES: + obj = ThemeBlog._meta.translations_model.objects.get(language_code = code,master__id=theme_id) #access to translated fields + data['name_%s'%code] = obj.name + data['description_%s'%code] = obj.description + data['main_title_%s'%code] = obj.main_title + form = ThemeBlogForm(data) + args = {} + args.update(csrf(request)) + args['form'] = form + args['languages'] = settings.LANGUAGES + args['theme_id'] = theme_id + + return render_to_response('admin/theme/theme_blog_new.html', args) + + + +# ====================================================== class ThemeBlogUpdateView(UpdateView): template_name = "admin/theme/theme_blog_new.html" model = ThemeBlog @@ -197,8 +230,8 @@ class ThemeBlogUpdateView(UpdateView): pk_url_kwarg = "theme_id" -class ThemeBlogDeleteView(DeleteView): - template_name = "admin/theme/theme_blog_confirm_delete.html" +class ThemeBlogCreateView(CreateView): + template_name = "admin/theme/theme_blog_new.html" model = ThemeBlog - success_url = reverse_lazy("theme_blog_all") - pk_url_kwarg = "theme_id" + form_class = ThemeBlogForm + success_url = reverse_lazy("theme_blog_all") \ No newline at end of file diff --git a/theme/admin_urls.py b/theme/admin_urls.py index 0caf5c87..423c6dc4 100644 --- a/theme/admin_urls.py +++ b/theme/admin_urls.py @@ -7,12 +7,12 @@ from .admin import ThemeBlogCreateView, ThemeBlogUpdateView, ThemeBlogDeleteView urlpatterns = patterns('theme.admin', url(r'^theme/add.*/$', 'theme_add'), url(r'^tag/add.*/$', 'tag_add'), - url(r'^blog_theme/add/$', ThemeBlogCreateView.as_view(), name = 'theme_blog_new'), + url(r'^blog_theme/add/$', 'blog_theme_add', name = 'theme_blog_new'), url(r'^theme/delete/(?P\d+)/$', 'theme_delete'), url(r'^tag/delete/(?P\d+)/$', 'tag_delete'), url(r'^blog_theme/delete/(?P\d+)/$', ThemeBlogDeleteView.as_view(), name = 'theme_blog_delete'), url(r'^theme/change/(?P\d+).*/$', 'theme_change'), - url(r'^blog_theme/change/(?P\d+).*/$', ThemeBlogUpdateView.as_view(), name= "theme_blog_change"), + url(r'^blog_theme/change/(?P\d+).*/$', 'blog_theme_change', name= "theme_blog_change"), url(r'^tag/change/(?P\d+).*/$', 'tag_change'), url(r'^theme/copy/(?P\d+).*/$', 'theme_copy'), url(r'^tag/copy/(?P\d+).*/$', 'tag_copy'), diff --git a/theme/forms.py b/theme/forms.py index 5f166b04..7571a784 100644 --- a/theme/forms.py +++ b/theme/forms.py @@ -149,7 +149,7 @@ from hvad.forms import TranslatableModelForm from .models import ThemeBlog -class ThemeBlogForm(TranslatableModelForm): +class _ThemeBlogForm(TranslatableModelForm): class Meta: model = ThemeBlog fields = ['url', 'name', 'main_title', 'description', 'inflect'] @@ -158,4 +158,34 @@ class ThemeBlogForm(TranslatableModelForm): def save(self, commit= True): if not 'url' in self.cleaned_data: self.cleaned_data['url'] = translit_with_separator(self.cleaned_data['name']) - return super(ThemeBlogForm, self).save(commit=True) \ No newline at end of file + return super(_ThemeBlogForm, self).save(commit=True) + + +class ThemeBlogForm(forms.Form): + + def __init__(self, *args, **kwargs): + super(ThemeBlogForm, 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['name_%s' % code] = forms.CharField(label='Название', required=required) + self.fields['main_title_%s' % code] = forms.CharField(label='Заголовок', required=required) + self.fields['description_%s' % code] = forms.CharField(label='Описание', required=False, widget=CKEditorWidget)#with saving form + + def save(self, id=None): + data = self.cleaned_data + if not id: + theme = ThemeBlog() + else: + theme = ThemeBlog.objects.get(id=id) + if not getattr(theme, 'url'): + theme.url = translit_with_separator(data['name_ru'].strip()).lower() + + fill_with_signal(ThemeBlog, theme, data) + if not theme.url: + theme.url = translit_with_separator(theme.name) + theme.save() diff --git a/theme/models.py b/theme/models.py index 93908fd7..dd01de1c 100644 --- a/theme/models.py +++ b/theme/models.py @@ -273,6 +273,7 @@ def pre_save_handler(sender, **kwargs): pre_save.connect(pre_save_handler, sender=Tag) post_save.connect(post_save_handler, sender=Theme) +post_save.connect(post_save_handler, sender=ThemeBlog) post_save.connect(post_save_handler, sender=Tag)