diff --git a/conference/models.py b/conference/models.py index 067371db..f1173103 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) 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/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 bfcf5ae2..8de663b0 100644 --- a/templates/admin/includes/admin_nav.html +++ b/templates/admin/includes/admin_nav.html @@ -108,6 +108,7 @@
  • Платные выставки
  • Выставки в топе
  • Выставки на главной
  • +
  • Конференции на главной
  • diff --git a/templates/admin/theme/theme_blog_new.html b/templates/admin/theme/theme_blog_new.html index fe5406b8..bd9fe715 100644 --- a/templates/admin/theme/theme_blog_new.html +++ b/templates/admin/theme/theme_blog_new.html @@ -7,7 +7,6 @@ {# selects #} - @@ -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/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)
    ВыставкаКонференцияВыставкаПозиция    
    {{ item }} {{ item.main.position }}Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Изменить {% if item.main.public %}отключить{% else %}включить{% endif %} Статистика