remotes/origin/1203
Nazar Kotjuk 10 years ago
commit 4147bd001b
  1. 5
      .gitignore
  2. 13
      article/admin.py
  3. 24
      article/forms.py
  4. 11
      article/models.py
  5. 8
      article/views.py
  6. 4
      conference/admin.py
  7. 2
      conference/forms.py
  8. 11
      conference/models.py
  9. 54
      expobanner/admin.py
  10. 6
      expobanner/admin_urls.py
  11. 32
      expobanner/forms.py
  12. 8
      expobanner/models.py
  13. 16
      exposition/models.py
  14. 17
      functions/model_mixin.py
  15. 16
      functions/models_methods.py
  16. 26
      proj/views.py
  17. 83
      service/admin.py
  18. 9
      service/admin_urls.py
  19. 61
      service/forms.py
  20. 1
      service/management/__init__.py
  21. 1
      service/management/commands/__init__.py
  22. 24
      service/management/commands/create_linked_services.py
  23. 106
      service/models.py
  24. 10
      templates/admin/article/blog_form.html
  25. 7
      templates/admin/conference/conference.html
  26. 10
      templates/admin/conference/conference_add.html
  27. 2
      templates/admin/expobanner/default_form.html
  28. 23
      templates/admin/expobanner/main_list.html
  29. 33
      templates/admin/expobanner/paid_create.html
  30. 3
      templates/admin/includes/admin_nav.html
  31. 39
      templates/admin/service/control_list.html
  32. 146
      templates/admin/service/linked_service.html
  33. 11
      templates/admin/service/linked_service_confirm_delete.html
  34. 46
      templates/admin/service/linked_service_list.html
  35. 2
      templates/admin/service/service_add.html
  36. 11
      templates/admin/theme/theme_blog_confirm_delete.html
  37. 65
      templates/admin/theme/theme_blog_list.html
  38. 50
      templates/admin/theme/theme_blog_new.html
  39. 4
      templates/client/article/article.html
  40. 15
      templates/client/includes/conference/conference_services.html
  41. 2
      templates/client/includes/conference/default_description.html
  42. 17
      templates/client/includes/exposition/exposition_services.html
  43. 2
      templates/client/includes/index/main_events.html
  44. 30
      templates/client/package.json
  45. 2
      templates/client/service/participation.html
  46. 2
      templates/client/service/remotely.html
  47. 2
      templates/client/service/tickets.html
  48. 2
      templates/client/service/tour.html
  49. 2
      templates/client/service/translator.html
  50. 1
      templates/client/static_client/css/vendor.css
  51. 7
      templates/client/static_client/js/_modules/block.common.js
  52. 2
      templates/client/static_client/js_min/_modules/block.common.min.js
  53. 76
      theme/admin.py
  54. 6
      theme/admin_urls.py
  55. 47
      theme/forms.py
  56. 25
      theme/models.py
  57. 3
      theme/views.py

5
.gitignore vendored

@ -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

@ -125,12 +125,14 @@ def article_change(request, url):
return render_to_response('article_add.html', args)
#-----------------------
from django.views.generic import ListView, FormView
from django.views.generic import FormView
from functions.custom_views import ListView
from forms import BlogForm
class BlogList(ListView):
model = Article
template_name = 'article/article_admin_list.html'
template_name = 'admin/article/article_admin_list.html'
paginate_by = settings.ADMIN_PAGINATION
def get_queryset(self):
return self.model.objects.blogs()
@ -140,9 +142,10 @@ class BlogList(ListView):
context['blog_flag'] = True
return context
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
@ -160,7 +163,6 @@ class BlogView(FormView):
form.save(author, article=self.obj)
return HttpResponseRedirect(self.success_url)
def get_form(self, form_class):
if self.request.POST:
return super(BlogView, self).get_form(form_class)
@ -168,7 +170,8 @@ class BlogView(FormView):
if self.obj:
article = self.obj
data = {}
data['theme'] = [item.id for item in article.theme.all()]
data['slug'] = article.slug
data['theme'] = [item.id for item in article.blog_theme.all()]
if article.exposition:
data['exposition'] = article.exposition.id
if article.conference:

@ -12,18 +12,20 @@ from functions.form_check import translit_with_separator
#models
from models import Article
from accounts.models import User
from theme.models import Theme, Tag
from theme.models import Theme, Tag, ThemeBlog
from exposition.models import Exposition
from conference.models import Conference
class BlogForm(forms.Form):
type = Article.blog
theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.exclude(article__id=None), required=False,
theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=ThemeBlog.objects.all(), required=False,
widget=forms.SelectMultiple(attrs={'style':'width: 550px'}))
slug = forms.SlugField(label=u'URL', max_length=255, min_length=1, required=False)
publish_date = forms.DateField(label=u'Дата публикации', input_formats=['%Y-%m-%d', '%d.%m.%Y'], required=False)
tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False)
logo = forms.ImageField(label=u'Лого', required=False)
def __init__(self, *args, **kwargs):
"""
create dynamical translated fields fields
@ -49,21 +51,26 @@ class BlogForm(forms.Form):
def save(self, author, article=None):
data = self.cleaned_data
#create new Article object or get exists
# create new Article object or get exists
if not article:
article = Article()
article.author = author
article.type = self.type
article.slug = data.get('slug')
if data['logo']:
article.logo = data['logo']
article.publish_date = data['publish_date']
# fill translated fields and save object
fill_with_signal(Article, article, data)
# fill manytomany fields
article.theme.clear()
if self.type == Article.blog:
article.blog_theme.clear()
article.blog_theme.add(*ThemeBlog.objects.filter(id__in=data['theme']))
else:
article.theme.clear()
article.theme.add(*Theme.objects.filter(id__in=data['theme']))
article.tag.clear()
article.theme.add(*Theme.objects.filter(id__in=data['theme']))
article.tag.add(*Tag.objects.filter(id__in=data['tag']))
#for item in data['theme']:
# article.theme.add(item.id)#.id cause select uses queryset
@ -92,7 +99,8 @@ class NewsForm(BlogForm):
type = Article.news
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput(), required=False)
conference = forms.CharField(label=u'Конференция', widget=forms.HiddenInput(), required=False)
theme = forms.ModelMultipleChoiceField(label='Тематики', queryset=Theme.objects.all(), required=False,
widget=forms.SelectMultiple(attrs={'style':'width: 550px'}))
#exposition = forms.ModelChoiceField(label = u'Выставка', required=False, queryset=Exposition.objects.all())
#conference = forms.ModelChoiceField(label = u'Конференция', required=False, queryset=Conference.objects.all())
@ -258,7 +266,7 @@ class BlogForm(forms.ModelForm):
class ArticleFilterForm(forms.Form):
theme = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().filter(article__type=1).exclude(article__id=None).distinct()])
choices=[(item.id, item.name) for item in ThemeBlog.objects.language().distinct()])
tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False)
'''
@ -284,7 +292,7 @@ class BlogFilterForm(forms.Form):
super(BlogFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme'] for item in list(Article.objects.blogs().values('theme').distinct())]
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False,
choices=[(item.id, item.name) for item in Theme.objects.language().filter(id__in=ids)])
choices=[(item.id, item.name) for item in ThemeBlog.objects.language().filter(id__in=ids)])
class NewsFilterForm(forms.Form):

@ -14,7 +14,6 @@ from functions.form_check import translit_with_separator
from django.core.cache import cache
class ArticleManager(TranslationManager):
cache_time = 60
def safe_get(self, **kwargs):
@ -60,7 +59,6 @@ class ArticleManager(TranslationManager):
cache.set(key, blogs, self.cache_time)
return blogs
return list(self.blogs().filter(publish_date__isnull=False).order_by('-main_page', '-publish_date')[:3])
class Article(TranslatableModel):
"""
@ -81,6 +79,7 @@ class Article(TranslatableModel):
old_id = models.IntegerField(blank=True, null=True)
logo = ImageField(upload_to='articles_preview', blank=True)
theme = models.ManyToManyField('theme.Theme')
blog_theme = models.ManyToManyField('theme.ThemeBlog')
tag = models.ManyToManyField('theme.Tag', blank=True, null=True)
author = models.ForeignKey('accounts.User', verbose_name='Автор',
on_delete=models.PROTECT, related_name='articles')
@ -148,15 +147,12 @@ class Article(TranslatableModel):
return self.conference
return None
def save(self, *args, **kwargs):
# If no slug is provided, generates one before saving.
if not self.slug:
self.slug = self.generate_unique_slug()
#Set the description field on save.
#if self.gen_description:
# Set the description field on save.
# if self.gen_description:
# self.description = strip_tags(self.description_from_content())
super(Article, self).save(*args, **kwargs)
@ -189,7 +185,6 @@ class Article(TranslatableModel):
#print self.lazy_translation_getter('main_title', self.pk)
return u'%s'%self.lazy_translation_getter('main_title', self.pk)
def _get_next_or_previous_by_publish_date(self, is_next, **kwargs):
"""
Retrieves next or previous object by publish date. We implement

@ -5,7 +5,7 @@ from functions.custom_views import ListView
from django.http import HttpResponse
from models import Article
from forms import ArticleFilterForm
from theme.models import Tag, Theme
from theme.models import Tag, Theme, ThemeBlog
from meta.views import MetadataMixin
@ -71,7 +71,7 @@ class BlogList(MetadataMixin, ListView):
themes = self.request.GET.getlist('theme')
if themes:
qs = qs.filter(theme__id__in=themes)
qs = qs.filter(blog_theme__id__in=themes)
tags = self.request.GET.getlist('tag')
if u'' in tags:
@ -180,10 +180,10 @@ class BlogsFilterCatalog(MetadataMixin, ListView):
self.filter_object = tag
qs = Article.objects.blogs().filter(tag=tag)
else:
theme = get_object_or_404(Theme, url=slug)
theme = get_object_or_404(ThemeBlog, url=slug)
self.kwargs['theme'] = theme
self.filter_object = theme
qs = Article.objects.blogs().filter(theme = theme)
qs = Article.objects.blogs().filter(blog_theme = theme)
year = self.kwargs.get('year')
if year:

@ -159,7 +159,7 @@ def conference_change(request, url):
#initial StatisticFormSet
StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('conference',))
#fill form with data from database
data = {'web_page':conference.web_page, 'foundation_year': conference.foundation_year,
data = {'web_page':conference.web_page, 'place_alt': conference.place_alt, '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, 'conference_id':conference.id, 'expohit': conference.expohit,
@ -233,7 +233,7 @@ class ConferenceView(AdminView):
return super(ConferenceView, self).get_form(form_class)
obj = self.set_obj()
if obj:
data = {'web_page':obj.web_page, 'foundation_year': obj.foundation_year,
data = {'web_page':obj.web_page, 'place_alt':obj.place_alt, 'foundation_year': obj.foundation_year,
'data_begin':obj.data_begin, 'data_end':obj.data_end, 'currency':obj.currency,
'tax':obj.tax, 'min_price':obj.min_price, 'max_price':obj.max_price,
'link':obj.link, 'conference_id':obj.id, 'expohit': obj.expohit, 'periodic':obj.periodic,

@ -56,6 +56,7 @@ class ConferenceCreateForm(forms.Form):
place = forms.ChoiceField(label=u'Место проведения', required=False,
choices=places)
place_alt = forms.CharField(label = u"Альтернативное название места", required=False)
#creates select input with empty choices cause it will be filled with ajax
city = forms.CharField(label=u'Город', widget=forms.HiddenInput())
@ -160,6 +161,7 @@ class ConferenceCreateForm(forms.Form):
conference.canceled = data['canceled']
conference.moved = data['moved']
conference.periodic = data['periodic']
conference.place_alt = data['place_alt']
# generates bitfield
flag = 0
if data['quality_label']:

@ -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:

@ -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'

@ -36,4 +36,10 @@ urlpatterns = patterns('expobanner.admin',
url(r'^main/$', MainCreate.as_view(), name='expobanner-create_main'),
url(r'^main/turn/(?P<pk>\d+)/(?P<status>.*)/$', main_turn, name='expobanner-main-turn'),
url(r'^main/(?P<pk>\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<pk>\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<pk>\d+)/(?P<status>.*)/$', main_turn, name='expobanner-conf-main-turn'),
#url(r'^main/conf/(?P<pk>\d+)/stat/$', MainStat.as_view(), name='expobanner_stat_main'),
)

@ -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'Линк на участие')

@ -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):

@ -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()

@ -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):

@ -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):

@ -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:

@ -117,28 +117,61 @@ 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
from .models import LinkedService
class LinkedServiceUpdateView(UpdateView):
form_class = LinkedServiceForm
model = LinkedService
template_name = "admin/service/linked_service.html"
success_url = "/admin/service/control/all/"
def get_object(self, queryset=None):
url = self.kwargs['url']
service = get_object_or_404(Service, url=url)
obj = LinkedService.objects.get(service=service)
return obj
def get_initial(self):
types = {0:[], 1:['expo'], 2:['conference'], 3:['expo', 'conference']}
initial = {
'expositions': ",".join("%s:%s"%(item.id, item.name) for item in self.object.expositions.all()),
'conferences': ",".join("%s:%s"%(item.id, item.name) for item in self.object.conferences.all()),
'type': types[self.object.service.type.mask]
}
return initial
def get_success_url(self):
return self.success_url
def form_valid(self, form):
obj = form.save()
obj.countries = form.cleaned_data['countries']
obj.expositions = form.cleaned_data['expositions']
obj.conferences = form.cleaned_data['conferences']
obj.save()
obj.update_all_flags()
return HttpResponseRedirect(self.get_success_url())
class LinkedServiceList(ListView):
model = LinkedService
template_name = 'admin/service/linked_service_list.html'
class LinkedServiceDeleteView(DeleteView):
model = LinkedService
template_name = 'admin/service/linked_service_confirm_delete.html'
success_url = '/admin/service/test/all'
slug_url_kwarg = 'url'
def get_object(self, queryset=None):
url = self.kwargs['url']
service = get_object_or_404(Service, url=url)
obj = LinkedService.objects.get(service=service)
return obj

@ -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
from service.admin import LinkedServiceList, LinkedServiceUpdateView, LinkedServiceDeleteView
urlpatterns = patterns('service.admin',
url(r'^control/list/$', ServiceControlList.as_view()),
url(r'^control/(?P<pk>.*)/$', ServiceControl.as_view()),
url(r'^add.*/$', 'service_add'),
url(r'^delete/(?P<url>.*)/$', 'service_delete'),
url(r'^change/(?P<url>.*)/$', 'service_change'),
@ -18,8 +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(r'^control/delete/(?P<url>[a-z]*)/', LinkedServiceDeleteView.as_view(), name='linked_service_delete'),
url(r'^control/all/', LinkedServiceList.as_view(), name='linked_service_all'),
url(r'^control/(?P<url>[a-z]*)/', LinkedServiceUpdateView.as_view(), name='linked_service_update'),
#ajax
url(r'^get_city/$', 'get_city'),
#url(r'^get_country/$', 'get_country'),
)

@ -128,22 +128,47 @@ 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(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
fields = ['countries', 'exclude_countries', 'expositions', 'conferences']
help_text = {
'exclude_countries': u'При отсутствии стран этот флаг значит ВСЕ страны!'
}
def clean_countries(self):
countries = Country.objects.language().filter(id__in=self.cleaned_data['countries'])
return countries
def clean_expositions(self):
expositions = EmptyQuerySet()
if self.cleaned_data.get('expositions'):
expositions = Exposition.objects.language().filter(id__in=list(set(self.cleaned_data['expositions'].split(','))))
return expositions
def clean_conferences(self):
conferences = EmptyQuerySet()
if self.cleaned_data.get('conferences'):
conferences = Conference.objects.language().filter(id__in=list(set(self.cleaned_data['conferences'].split(','))))
return conferences
def save(self, commit=True):
obj = super(LinkedServiceForm, self).save(commit=True)
data = self.cleaned_data
# manage service type bit field
types = data['type']
obj.service.type = 0
for type in types:
obj.service.type = obj.service.type | getattr(Service.type, type)
obj.service.save()
return obj

@ -0,0 +1 @@
__author__ = 'dev'

@ -0,0 +1,24 @@
from django.core.management.base import BaseCommand
from django.utils.translation import activate
from service.models import Service,LinkedService
from country.models import Country
from exposition.models import Exposition
from conference.models import Conference
class Command(BaseCommand):
def handle(self, *args, **options):
activate('ru')
LinkedService.objects.all().delete()
services = Service.objects.all()
for service in services:
linked = LinkedService()
linked.service = service
linked.save()
if Country.objects.language().filter(services=getattr(Country.services, service.url)).count() > 180:
linked.exclude_countries = True
linked.countries = Country.objects.language().exclude(services=getattr(Country.services, service.url))
else:
linked.countries = Country.objects.language().filter(services=getattr(Country.services, service.url))
linked.save()

@ -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
@ -198,4 +144,54 @@ class CallBack(models.Model):
viewed = models.DateTimeField(null=True, blank=True)
class Meta:
ordering = ['-created']
ordering = ['-created']
from country.models import Country
from exposition.models import Exposition
from conference.models import Conference
from django.db.models import F
class LinkedService(models.Model):
service = models.ForeignKey(Service, blank=False)
countries = models.ManyToManyField(Country, blank=True, verbose_name=u"Страны")
exclude_countries = models.BooleanField(default=False, verbose_name=u"Исключить страны")
expositions = models.ManyToManyField(Exposition, blank=True, verbose_name= u"Выставки")
conferences = models.ManyToManyField(Conference, blank=True, verbose_name=u'Конференции')
def update_countries_flag(self):
if self.exclude_countries:
'filter all countries except selected and set flag to true'
Country.objects.language().exclude(id__in=[c.id for c in self.countries.all()]).update(services=F('services').bitor(getattr(Country.services, self.service.url)))
'set another flags to false'
Country.objects.language().filter(id__in=[c.id for c in self.countries.all()]).update(services=F('services').bitand(~getattr(Country.services, self.service.url)))
else:
'if not exclude, filter all selected countries and set flag to true'
self.countries.update(services=F('services').bitor(getattr(Country.services, self.service.url)))
Country.objects.exclude(id__in=[c.id for c in self.countries.all()]).update(services=F('services').bitand(~getattr(Country.services, self.service.url)))
def update_expositions_flag(self):
self.expositions.update(services=F('services').bitor(getattr(Exposition.services, self.service.url)))
Exposition.objects.exclude(id__in=[c.id for c in self.expositions.all()]).update(services=F('services').bitand(~getattr(Exposition.services, self.service.url)))
def update_conferences_flag(self):
self.conferences.update(services=F('services').bitor(getattr(Conference.services, self.service.url)))
Conference.objects.exclude(id__in=[c.id for c in self.conferences.all()]).update(services=F('services').bitand(~getattr(Conference.services, self.service.url)))
def update_all_flags(self):
self.update_countries_flag()
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

@ -51,7 +51,15 @@
<span class="help-inline">{{ form.publish_date.errors }}</span>
</div>
</div>
{% if not article %}
<div class="control-group {% if form.slug.errors %}error{% endif %}">
<label class="control-label">{{ form.slug.label }}:</label>
<div class="controls">
{{ form.slug }}
<span class="help-inline">{{ form.slug.errors }}</span>
</div>
</div>
{% endif %}
{# theme #}
<div class="control-group {% if form.theme.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.theme.label }}:</b></label>

@ -134,6 +134,13 @@
<span class="help-inline">{{ form.place.errors }}</span>
</div>
</div>
{# place_alt #}
<div class="control-group {% if form.place_alt.errors %}error{% endif %}">
<label class="control-label">{{ form.place_alt.label }}:</label>
<div class="controls">{{ form.place_alt }}
<span class="help-inline">{{ form.place_alt.errors }}</span>
</div>
</div>
{# theme #}
<div class="control-group {% if form.theme.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.theme.label }}:</b></label>

@ -47,7 +47,7 @@
<div class="box span8" >
<div class="box-header well">
<h2><i class="icon-pencil"></i> Основная информация</h2>
<h2><i class="icon-pencil"></i> Основная информаdция</h2>
</div>
<div class="box-content">
{# Hidden inputs uses for comparing with TmpFile objects #}
@ -99,6 +99,14 @@
<span class="help-inline">{{ form.place.errors }}</span>
</div>
</div>
{# place #}
<div class="control-group {% if form.place_alt.errors %}error{% endif %}">
<label class="control-label">{{ form.place_alt.label }}:</label>
<div class="controls">{{ form.place_alt }}
<span class="help-inline">{{ form.place_alt.errors }}</span>
</div>
</div>
{# theme #}
<div class="control-group {% if form.theme.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.theme.label }}:</b></label>

@ -51,7 +51,7 @@
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i>{{ form.verbose }}</h2>
<h2><i class="icon-pencil"></i> {% if form.verbose %} {{ form.verbose }} {% else %} {{ object.get_event }} {% endif %}</h2>
</div>
<div class="box-content">
{% for field in form %}

@ -4,13 +4,17 @@
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Список выставок на главной</h2>
<h2><i class="icon-arrow-down"></i>Список {% if conf %}конференций{% else %}выставок{% endif %} на главной</h2>
</div>
<div class="box-content">
{% block list_table %}
<div style="float:left;">
{% if conf %}
<a class="btn btn-success" href="{% url 'expobanner-conf-create_main' %}"><i class="icon-plus-sign icon-white"></i> Добавить конференцию</a>
{% else %}
<a class="btn btn-success" href="{% url 'expobanner-create_main' %}"><i class="icon-plus-sign icon-white"></i> Добавить выставку</a>
</div>
{% endif %}
</div>
<div style="float:right;">
<form method="get" id="form">
Только опубликование<input id="public" type="checkbox" name="onlypublic" value="true">
@ -19,7 +23,11 @@
<table class="table table-hover">
<thead>
<tr>
<th>Выставка</th>
{% if conf %}
<th>Конференция</th>
{% else %}
<th>Выставка</th>
{% endif %}
<th>Позиция</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
@ -31,8 +39,13 @@
<tr>
<td>{{ item }}</td>
<td>{{ item.main.position }}</td>
<td><a href="{% url 'expobanner-update_main' item.main.id %}">Изменить</a> </td>
<td>{% if item.main.public %}<a href="{% url 'expobanner-main-turn' item.main.id 'off' %}">отключить</a>{% else %}<a href="{% url 'expobanner-main-turn' item.main.id 'on' %}">включить</a>{% endif %} </td>
{% if conf %}
<td><a href="{% url 'expobanner-conf-update_main' item.main.id %}">Изменить</a> </td>
<td>{% if item.main.public %}<a href="{% url 'expobanner-conf-main-turn' item.main.id 'off' %}">отключить</a>{% else %}<a href="{% url 'expobanner-conf-main-turn' item.main.id 'on' %}">включить</a>{% endif %} </td>
{% else %}
<td><a href="{% url 'expobanner-update_main' item.main.id %}">Изменить</a> </td>
<td>{% if item.main.public %}<a href="{% url 'expobanner-main-turn' item.main.id 'off' %}">отключить</a>{% else %}<a href="{% url 'expobanner-main-turn' item.main.id 'on' %}">включить</a>{% endif %} </td>
{% endif %}
<td><a href="{% url 'expobanner_stat_main' item.main.id %}">Статистика</a> </td>
</tr>
{% endfor %}

@ -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});
}
});
});
</script>
{% endblock %}

@ -40,8 +40,10 @@
<li><a href="/admin/country/all">Страна</a></li>
<li><a href="/admin/city/all">Город</a></li>
<li><a href="/admin/theme/theme/all">Тематики</a></li>
<li><a href="/admin/theme/blog_theme/all">Тематики для блогов</a></li>
<li><a href="/admin/theme/tag/all">Теги</a></li>
<li><a href="/admin/service/all">Услуги</a></li>
<li><a href="{% url 'linked_service_all' %}">Управление услугами</a></li>
<li><a href="/admin/settings/main-page/">Главная страница</a></li>
<li><a href="/admin/meta/all/">Мета</a></li>
@ -106,6 +108,7 @@
<li><a href="/admin/expobanners/paid/list/">Платные выставки</a></li>
<li><a href="/admin/expobanners/top/list/">Выставки в топе</a></li>
<li><a href="/admin/expobanners/main/list/">Выставки на главной</a></li>
<li><a href="/admin/expobanners/main/conf/list/">Конференции на главной</a></li>
</ul>
</li>

@ -1,39 +0,0 @@
{% extends 'admin_list.html' %}
{% block body %}
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Список услуг</h2>
</div>
<div class="box-content">
<table class="table table-hover">
<thead>
<tr>
<th>id</th>
<th>Название</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>
<a class="btn-small btn-info" href="/admin/service/control/{{ item.id }}/">
Управлять
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div>
{% endblock %}

@ -0,0 +1,146 @@
{% extends 'base.html' %}
{% load static %}
{% block scripts %}
{# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<style>
ul {
list-style: none;
}
</style>
<script src="{% static 'js/select/select2.js' %}"></script>
<script>
$(document).ready(function () {
console.log(1);
$("#id_countries").select2({width:'element'});
$('#id_expositions').select2({
placeholder: "Expositions",
width: 'element',
multiple: true,
ajax: {
url: "/admin/exposition/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 data = [];
var values = element.val();
element.val("");
$(values.split(",")).each(function (i) {
var item = this.split(':');
data.push({
id: item[0],
text: item[1]
});
});
console.log("initselection data: ");
console.log(data);
callback(data);
}
});
$('#id_conferences').select2({
placeholder: "Conferences",
width: 'element',
multiple: true,
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 data = [];
var values = element.val();
element.val("");
$(values.split(",")).each(function (i) {
var item = this.split(':');
data.push({
id: item[0],
text: item[1]
});
});
callback(data);
}
});
});
</script>
{% endblock %}
{% block body %}
{# Uses multilang.html template for translated fields #}
<form class="form-horizontal" method="post" action="">{% csrf_token %}
<fieldset>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> </h2>
</div>
<div class="box-content">
{% for f in form %}
<div class="control-group {% if f.errors %}error{% endif %}">
<label class="control-label"><b>{{ f.label }}:</b></label>
<div class="controls">{{ f }}
<span class="help-inline">{{ f.errors }}</span>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="controls">
<button type="submit" class="btn btn-large btn-primary">Submit</button>
<button type="reset" class="btn btn-large">Reset</button>
</div>
</fieldset>
</form>
{% endblock %}

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% block sidebar %}{% endblock %}
{% block body %}
<form action="" method="post">{% csrf_token %}
<div class="controls">
<p>Вы точно хотите удалить настройку для сервиса "{{ object.service.name }}" ?</p>
<input class="btn btn-large btn-danger delete" type="submit" value="Да" />
<a class="btn btn-large btn-primary" href = {% url 'linked_service_all' %}>Нет</a>
</div>
</form>
{% endblock %}

@ -0,0 +1,46 @@
{% extends 'base.html' %}
{% block body %}
<div class="box span10">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Настройки услуг</h2>
</div>
<div class="box-content">
<table class="table table-hover">
<thead>
<tr>
<th>id</th>
<th>Название услуги</th>
<th>Тип</th>
<th>Стран</th>
<th>Виставок</th>
<th>Конференций</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{{ object }}
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.service.name }}</td>
<td>{% if item.service.type.mask == 1 %} выставки {% elif item.service.type.mask == 2%} конференции {% elif item.service.type.mask == 3 %} выставки и конференции{% endif %}</td>
<td>{{ item.countries_count }}</td>
<td>{{ item.expositions.count }}</td>
<td>{{ item.conferences.count }}</td>
<td class="center sorting_1">
<a class="btn btn-info" href="{% url 'linked_service_update' item.service.url %}">
<i class="icon-edit icon-white"></i> Управление
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

@ -48,7 +48,7 @@
{% include 'admin/forms/multilang.html' %}
{% endwith %}
{# url #}
<div class="control-group {% if form.url.errors %}error{% endif %}">
<div class="control-group {% if form.url.errors %}error{% endif %}">
<label class="control-label">{{ form.url.label }}:</label>
<div class="controls">
{{ form.url }}

@ -0,0 +1,11 @@
{% extends 'base.html' %}
{% block sidebar %}{% endblock %}
{% block body %}
<form action="" method="post">{% csrf_token %}
<div class="controls">
<p>Вы точно хотите удалить "{{ object.name }}" ?</p>
<input class="btn btn-large btn-danger delete" type="submit" value="Да" />
<a class="btn btn-large btn-primary" href = {% url 'theme_blog_all' %}>Нет</a>
</div>
</form>
{% endblock %}

@ -0,0 +1,65 @@
{% extends 'admin_list.html' %}
{% block body %}
{#<div class="box span8">#}
{# <div class="box-header well">#}
{# <h2><i class="icon-arrow-down"></i>Фильтры</h2>#}
{# </div>#}
{# <div class="box-content">#}
{# <form>#}
{# {{ form }}#}
{##}
{# <button type="submit" class="btn">Найти</button>#}
{# </form>#}
{# </div>#}
{##}
{#</div>#}
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Список тем</h2>
</div>
<div class="box-content">
<table class="table table-hover">
<colgroup>
<col width="10%">
<col width="70%">
<col width="10%">
<col width="10%">
</colgroup>
<thead>
<tr>
<th>id</th>
<th>Название</th>
<th>&nbsp;</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for item in object_list %}
<tr>
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td class="center sorting_1">
<a class="btn-small btn-info" href="{% url "theme_blog_change" item.id %}">
Изменить
</a>
</td>
<td>
<a class="btn-small btn-danger delete" href="{% url "theme_blog_delete" item.id %}">
Удалить
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="btn btn-success" href="{% url "theme_blog_new" %}"><i class="icon-plus-sign icon-white"></i> Добавить тематику</a>
</div>
{# pagination #}
{% include 'admin/includes/admin_pagination.html' with page_obj=object_list %}
</div>
{% endblock %}

@ -0,0 +1,50 @@
{% extends 'base.html' %}
{% load static %}
{% block scripts %}
<script src="{% static 'ckeditor/ckeditor/ckeditor.js' %}"></script>
{# selects #}
<link href="{% static 'js/select/select2.css' %}" rel="stylesheet"/>
<script src="{% static 'js/select/select2.js' %}"></script>
{% endblock %}
{% block body %}
<form method="post" class="form-horizontal" > {% csrf_token %}
<fieldset>
<legend><i class="icon-edit"></i>{% if theme_id %} Изменить {% else %} Добавить {% endif %}тему</legend>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i> Информация</h2>
</div>
<div class="box-content">
{# 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 %}
</div>
</div>
<div class="controls">
<input class="btn btn-large btn-primary" type="submit" value="Добавить">
<input class="btn btn-large" type="reset" value="Отмена">
</div>
</fieldset>
</form>
{% endblock %}

@ -19,7 +19,7 @@
{% include 'client/includes/article/article_logo.html' with obj=object %}
<h1>{{ object.main_title }}</h1>
<strong><span>{{ object.publish_date|date:"d E Y" }}</span>{% if object.theme.all.exists %}{% include 'includes/article_theme.html' with obj=object %}{% endif %}</strong>
<strong><span>{{ object.publish_date|date:"d E Y" }}</span>{% if object.blog_theme.all.exists %}{% include 'client/includes/article_theme.html' with obj=object %}{% endif %}</strong>
{% if request.user.is_admin %}
<a target="_blank" class="button green " href="/admin/article/blog/{{ object.slug }}/">{% trans 'изменить' %}</a>
{% endif %}
@ -54,7 +54,7 @@
<a href="{{ blog.get_permanent_url }}" title="">{% include 'includes/show_logo.html' with obj=blog %}</a>
<h3><a href="{{ blog.get_permanent_url }}" title="">{{ blog.main_title }}</a></h3>
<p>{{ blog.preview }}</p>
<strong><span>{{ blog.created|date:"d E Y" }}</span><a href="{{ blog.author.get_permanent_url }}" title=""><i>Евгения Булавина</i></a></strong>
<strong><span>{{ blog.publish_date|date:"d E Y" }}</span><a href="{{ blog.author.get_permanent_url }}" title=""><i>Евгения Булавина</i></a></strong>
</div>
</div>
{% endfor %}

@ -2,13 +2,12 @@
<div class="i-sub-articles">
<ul>
<li>
<a href="{{ event.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a>
</li>
{% if event.country_id not in sng_countries %}
<li>
<a href="{{ event.get_permanent_url }}service/visit/">{% trans 'Бизнес-тур "под ключ"' %}</a>
</li>
{% endif %}
{% with services=object.get_services_detail %}
{% for service in services %}
<li>
<a href="{{ exposition.get_permanent_url }}service/{{ service.url }}/">{{ service.name }}</a>
</li>
{% endfor %}
{% endwith %}
</ul>
</div>

@ -2,7 +2,7 @@
<div class="ied-text" style="text-align: justify">
{% blocktrans with name=conf.name%}
<p>Конференция {{name}} проходит {% endblocktrans %}{% include 'client/includes/show_date_block.html' with obj=conf %}
{% blocktrans with city=conf.name country=country.name name=conf.name id=conf.city.id code=request.LANGUAGE_CODE date1=conf.data_begin|date:'j' date2=conf.data_begin|date:'Y' date3=conf.data_begin|date:'n' date4=conf.data_end|date:'j' date5=conf.data_end|date:'Y' date6=conf.data_end|date:'n' %}
{% blocktrans with city=city.name country=country.name name=conf.name id=conf.city.id code=request.LANGUAGE_CODE date1=conf.data_begin|date:'j' date2=conf.data_begin|date:'Y' date3=conf.data_begin|date:'n' date4=conf.data_end|date:'j' date5=conf.data_end|date:'Y' date6=conf.data_end|date:'n' %}
в городе {{city}}, {{country}}.
Посмотреть, как проехать в место проведения конференции, можно на сайте конгрессной площадки.
Деловая программа {{name}} разбита на секции по дням и размещается на сайте мероприятия с подробным списком

@ -2,15 +2,12 @@
<div class="i-sub-articles">
<ul>
<li>
<a href="{{ exposition.get_permanent_url }}service/participation/">{% trans 'Участие со стендом' %}</a>
</li>
<li>
<a href="{{ exposition.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a>
</li>
<li>
<a href="{{ exposition.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a>
</li>
{% with services=object.get_services_detail %}
{% for service in services %}
<li>
<a href="{{ exposition.get_permanent_url }}service/{{ service.url }}/">{{ service.name }}</a>
</li>
{% endfor %}
{% endwith %}
</ul>
</div>

@ -36,7 +36,7 @@
<div class="re-buttons">
<a class="button blue icon-calendar {% if event|in_calendar:request.user %}removecalendar {% else %}addcalendar {% endif %}" href="{{ event.get_calendar_url }}">{% if event|in_calendar:request.user %}{% trans 'Убрать из календаря' %}{% else %}{% trans 'добавить в календарь' %}{% endif %}</a>
<div class="main-page {% if request.user.is_authenticated%}note-wrap{% else %}note-wrap-disabled{% endif %}">
<a class="button green icon-note {% if note %}active{% endif %} note-button" href="/expo/add-note/{{ event.url }}/">{% trans 'заметка' %}</a>
<a class="button green icon-note {% if note %}active{% endif %} note-button" href="{{ event.get_note_url }}">{% trans 'заметка' %}</a>
<div class="note-overlay">
<form action="">
<textarea name="note_text" class="note-text"> {{ note }}</textarea>

@ -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"
}

@ -55,7 +55,7 @@
</div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
<form method="post">{% csrf_token %}
<form id="id_service_participation" method="post">{% csrf_token %}
<hr />

@ -58,7 +58,7 @@
</div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
<form method="post">{% csrf_token %}
<form id="id_service_remote" method="post">{% csrf_token %}
<hr />

@ -51,7 +51,7 @@
</div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
<form method="post">{% csrf_token %}
<form id="id_service_tickets" method="post">{% csrf_token %}
<hr />

@ -53,7 +53,7 @@
</div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
<form method="post">{% csrf_token %}
<form id="id_service_tour" method="post">{% csrf_token %}
<hr />

@ -51,7 +51,7 @@
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}>
{% comment %}{{ form.errors }}{% endcomment %}
<form method="post">{% csrf_token %}
<form id="id_service_translator" method="post">{% csrf_token %}
<hr />

@ -2809,4 +2809,3 @@ html[dir="rtl"] .select2-container-multi .select2-choices li
height: 100px;
overflow: scroll;
}

@ -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{

File diff suppressed because one or more lines are too long

@ -3,15 +3,13 @@ from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect, HttpResponse
from django.core.context_processors import csrf
from django.conf import settings
from django.forms.formsets import BaseFormSet, formset_factory
from django.forms.models import modelformset_factory
from django.contrib.contenttypes.models import ContentType
from django.views.generic import CreateView, UpdateView, DeleteView
from django.contrib.auth.decorators import login_required
#forms and models
from forms import ThemeForm, TagForm, ThemeDeleteForm, TagDeleteForm, TagFilterForm, ThemeFilterForm
from models import Theme, Tag
from models import Theme, Tag, ThemeBlog
#custom views
from functions.custom_views import objects_list, add_object, delete_object
from functions.custom_views import objects_list, add_object, delete_object, ListView
from functions.views_help import get_referer
from functions.admin_views import AdminListView
@ -170,4 +168,70 @@ class ThemeListView(AdminListView):
class TagListView(AdminListView):
template_name = 'admin/theme/tag_list.html'
form_class = TagFilterForm
model = Tag
model = Tag
from functions.custom_views import ListView
from django.core.urlresolvers import reverse_lazy
from .forms import ThemeBlogForm
class ThemeBlogListView(ListView):
template_name = 'admin/theme/theme_blog_list.html'
model = ThemeBlog
paginate_by = settings.ADMIN_PAGINATION
class ThemeBlogDeleteView(DeleteView):
template_name = "admin/theme/theme_blog_confirm_delete.html"
model = ThemeBlog
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
form_class = ThemeBlogForm
success_url = reverse_lazy("theme_blog_all")
pk_url_kwarg = "theme_id"
class ThemeBlogCreateView(CreateView):
template_name = "admin/theme/theme_blog_new.html"
model = ThemeBlog
form_class = ThemeBlogForm
success_url = reverse_lazy("theme_blog_all")

@ -1,19 +1,25 @@
# -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url
from admin import TagListView, ThemeListView
from .admin import ThemeBlogCreateView, ThemeBlogUpdateView, ThemeBlogDeleteView, ThemeBlogListView
urlpatterns = patterns('theme.admin',
url(r'^theme/add.*/$', 'theme_add'),
url(r'^tag/add.*/$', 'tag_add'),
url(r'^blog_theme/add/$', 'blog_theme_add', name = 'theme_blog_new'),
url(r'^theme/delete/(?P<theme_id>\d+)/$', 'theme_delete'),
url(r'^tag/delete/(?P<tag_id>\d+)/$', 'tag_delete'),
url(r'^blog_theme/delete/(?P<theme_id>\d+)/$', ThemeBlogDeleteView.as_view(), name = 'theme_blog_delete'),
url(r'^theme/change/(?P<theme_id>\d+).*/$', 'theme_change'),
url(r'^blog_theme/change/(?P<theme_id>\d+).*/$', 'blog_theme_change', name= "theme_blog_change"),
url(r'^tag/change/(?P<tag_id>\d+).*/$', 'tag_change'),
url(r'^theme/copy/(?P<theme_id>\d+).*/$', 'theme_copy'),
url(r'^tag/copy/(?P<tag_id>\d+).*/$', 'tag_copy'),
#url(r'^theme/all/$', 'theme_all'),
#url(r'^tag/all/$', 'tag_all'),
url(r'^theme/all/$', ThemeListView.as_view()),
url(r'^blog_theme/all/$', ThemeBlogListView.as_view(), name="theme_blog_all"),
url(r'^tag/all/$', TagListView.as_view()),
url(r'^tag/search/$', 'search_tag'),
url(r'^tag/search-without-theme/$', 'search2'),

@ -143,4 +143,49 @@ class ThemeFilterForm(AdminFilterForm):
class TagFilterForm(AdminFilterForm):
model = Tag
model = Tag
from hvad.forms import TranslatableModelForm
from .models import ThemeBlog
class _ThemeBlogForm(TranslatableModelForm):
class Meta:
model = ThemeBlog
fields = ['url', 'name', 'main_title', 'description', 'inflect']
widgets = {'url':forms.TextInput(attrs={'required':False})}
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)
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()

@ -133,6 +133,30 @@ class Theme(TranslatableModel):
parent = {}
return parent
class ThemeBlog(TranslatableModel):
url = models.SlugField(unique=True, max_length=255)
translations = TranslatedFields(
name=models.CharField(max_length=255),
main_title=models.CharField(max_length=255, blank=True),
description=models.TextField(blank=True)
)
inflect = models.CharField(max_length=255, blank=True)
def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk))
def get_all_names(self):
return [item['name'] for item in self.translations.all().values('name')]
def get_index_text(self):
translation.activate('ru')
return ' '.join(self.get_all_names())
from django.db import IntegrityError
class Tag(TranslatableModel):
"""
@ -249,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)

@ -21,11 +21,8 @@ def get_tag(request):
def get_article_tags(request):
themes = request.GET.getlist('themes[]')
term = request.GET['term'].capitalize()
qs = Tag.objects.language().exclude(article=None).filter(article__type=1).distinct()
if themes:
qs = qs.filter(theme__id__in=themes).order_by('translations__name')
if term:
qs = qs.filter(translations__name__contains=term)
result = [{'id': tag.id, 'label': '%s (%s)'%(tag.name, tag.theme.name)} for tag in qs]

Loading…
Cancel
Save