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 *.egg-info
*.doc *.doc
# jetbrains data
.idea/ .idea/
media/ media/
media media
logs/ logs/
Thumbs.db Thumbs.db
npm-debug.log
/proj/local.py /proj/local.py
# gulp
node_modules node_modules
npm-debug.log

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

@ -12,18 +12,20 @@ from functions.form_check import translit_with_separator
#models #models
from models import Article from models import Article
from accounts.models import User from accounts.models import User
from theme.models import Theme, Tag from theme.models import Theme, Tag, ThemeBlog
from exposition.models import Exposition from exposition.models import Exposition
from conference.models import Conference from conference.models import Conference
class BlogForm(forms.Form): class BlogForm(forms.Form):
type = Article.blog 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'})) 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) 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) tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False)
logo = forms.ImageField(label=u'Лого', required=False) logo = forms.ImageField(label=u'Лого', required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
create dynamical translated fields fields create dynamical translated fields fields
@ -49,21 +51,26 @@ class BlogForm(forms.Form):
def save(self, author, article=None): def save(self, author, article=None):
data = self.cleaned_data data = self.cleaned_data
#create new Article object or get exists # create new Article object or get exists
if not article: if not article:
article = Article() article = Article()
article.author = author article.author = author
article.type = self.type article.type = self.type
article.slug = data.get('slug')
if data['logo']: if data['logo']:
article.logo = data['logo'] article.logo = data['logo']
article.publish_date = data['publish_date'] article.publish_date = data['publish_date']
# fill translated fields and save object # fill translated fields and save object
fill_with_signal(Article, article, data) fill_with_signal(Article, article, data)
# fill manytomany fields # 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.tag.clear()
article.theme.add(*Theme.objects.filter(id__in=data['theme']))
article.tag.add(*Tag.objects.filter(id__in=data['tag'])) article.tag.add(*Tag.objects.filter(id__in=data['tag']))
#for item in data['theme']: #for item in data['theme']:
# article.theme.add(item.id)#.id cause select uses queryset # article.theme.add(item.id)#.id cause select uses queryset
@ -92,7 +99,8 @@ class NewsForm(BlogForm):
type = Article.news type = Article.news
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput(), required=False) exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput(), required=False)
conference = 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()) #exposition = forms.ModelChoiceField(label = u'Выставка', required=False, queryset=Exposition.objects.all())
#conference = forms.ModelChoiceField(label = u'Конференция', required=False, queryset=Conference.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): class ArticleFilterForm(forms.Form):
theme = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False, 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) tag = forms.CharField(label=_(u'Теги:'), widget=forms.HiddenInput(), required=False)
''' '''
@ -284,7 +292,7 @@ class BlogFilterForm(forms.Form):
super(BlogFilterForm, self).__init__(*args, **kwargs) super(BlogFilterForm, self).__init__(*args, **kwargs)
ids = [item['theme'] for item in list(Article.objects.blogs().values('theme').distinct())] ids = [item['theme'] for item in list(Article.objects.blogs().values('theme').distinct())]
self.fields['theme'] = forms.MultipleChoiceField(label=_(u'Тематика:'), required=False, 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): class NewsFilterForm(forms.Form):

@ -14,7 +14,6 @@ from functions.form_check import translit_with_separator
from django.core.cache import cache from django.core.cache import cache
class ArticleManager(TranslationManager): class ArticleManager(TranslationManager):
cache_time = 60 cache_time = 60
def safe_get(self, **kwargs): def safe_get(self, **kwargs):
@ -60,7 +59,6 @@ class ArticleManager(TranslationManager):
cache.set(key, blogs, self.cache_time) cache.set(key, blogs, self.cache_time)
return blogs return blogs
return list(self.blogs().filter(publish_date__isnull=False).order_by('-main_page', '-publish_date')[:3])
class Article(TranslatableModel): class Article(TranslatableModel):
""" """
@ -81,6 +79,7 @@ class Article(TranslatableModel):
old_id = models.IntegerField(blank=True, null=True) old_id = models.IntegerField(blank=True, null=True)
logo = ImageField(upload_to='articles_preview', blank=True) logo = ImageField(upload_to='articles_preview', blank=True)
theme = models.ManyToManyField('theme.Theme') theme = models.ManyToManyField('theme.Theme')
blog_theme = models.ManyToManyField('theme.ThemeBlog')
tag = models.ManyToManyField('theme.Tag', blank=True, null=True) tag = models.ManyToManyField('theme.Tag', blank=True, null=True)
author = models.ForeignKey('accounts.User', verbose_name='Автор', author = models.ForeignKey('accounts.User', verbose_name='Автор',
on_delete=models.PROTECT, related_name='articles') on_delete=models.PROTECT, related_name='articles')
@ -148,15 +147,12 @@ class Article(TranslatableModel):
return self.conference return self.conference
return None return None
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
# If no slug is provided, generates one before saving. # If no slug is provided, generates one before saving.
if not self.slug: if not self.slug:
self.slug = self.generate_unique_slug() self.slug = self.generate_unique_slug()
# Set the description field on save.
#Set the description field on save. # if self.gen_description:
#if self.gen_description:
# self.description = strip_tags(self.description_from_content()) # self.description = strip_tags(self.description_from_content())
super(Article, self).save(*args, **kwargs) super(Article, self).save(*args, **kwargs)
@ -189,7 +185,6 @@ class Article(TranslatableModel):
#print self.lazy_translation_getter('main_title', self.pk) #print self.lazy_translation_getter('main_title', self.pk)
return u'%s'%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): def _get_next_or_previous_by_publish_date(self, is_next, **kwargs):
""" """
Retrieves next or previous object by publish date. We implement 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 django.http import HttpResponse
from models import Article from models import Article
from forms import ArticleFilterForm from forms import ArticleFilterForm
from theme.models import Tag, Theme from theme.models import Tag, Theme, ThemeBlog
from meta.views import MetadataMixin from meta.views import MetadataMixin
@ -71,7 +71,7 @@ class BlogList(MetadataMixin, ListView):
themes = self.request.GET.getlist('theme') themes = self.request.GET.getlist('theme')
if themes: if themes:
qs = qs.filter(theme__id__in=themes) qs = qs.filter(blog_theme__id__in=themes)
tags = self.request.GET.getlist('tag') tags = self.request.GET.getlist('tag')
if u'' in tags: if u'' in tags:
@ -180,10 +180,10 @@ class BlogsFilterCatalog(MetadataMixin, ListView):
self.filter_object = tag self.filter_object = tag
qs = Article.objects.blogs().filter(tag=tag) qs = Article.objects.blogs().filter(tag=tag)
else: else:
theme = get_object_or_404(Theme, url=slug) theme = get_object_or_404(ThemeBlog, url=slug)
self.kwargs['theme'] = theme self.kwargs['theme'] = theme
self.filter_object = 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') year = self.kwargs.get('year')
if year: if year:

@ -159,7 +159,7 @@ def conference_change(request, url):
#initial StatisticFormSet #initial StatisticFormSet
StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('conference',)) StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('conference',))
#fill form with data from database #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, '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, 'tax':conference.tax, 'min_price':conference.min_price, 'max_price':conference.max_price,
'link':conference.link, 'conference_id':conference.id, 'expohit': conference.expohit, '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) return super(ConferenceView, self).get_form(form_class)
obj = self.set_obj() obj = self.set_obj()
if 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, '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, '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, '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, place = forms.ChoiceField(label=u'Место проведения', required=False,
choices=places) choices=places)
place_alt = forms.CharField(label = u"Альтернативное название места", required=False)
#creates select input with empty choices cause it will be filled with ajax #creates select input with empty choices cause it will be filled with ajax
city = forms.CharField(label=u'Город', widget=forms.HiddenInput()) city = forms.CharField(label=u'Город', widget=forms.HiddenInput())
@ -160,6 +161,7 @@ class ConferenceCreateForm(forms.Form):
conference.canceled = data['canceled'] conference.canceled = data['canceled']
conference.moved = data['moved'] conference.moved = data['moved']
conference.periodic = data['periodic'] conference.periodic = data['periodic']
conference.place_alt = data['place_alt']
# generates bitfield # generates bitfield
flag = 0 flag = 0
if data['quality_label']: if data['quality_label']:

@ -111,6 +111,7 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
keywords=models.CharField(max_length=250), 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 #fields saves information about creating and changing model
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True) modified = models.DateTimeField(auto_now=True)
@ -132,6 +133,13 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
return list(qs) return list(qs)
#return list(Service.objects.language().filter(url__in=ids, type=Service.type.conference).order_by('sort')) #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): def get_nearest_events(self):
if self.theme.all(): if self.theme.all():
theme = self.theme.all()[0] theme = self.theme.all()[0]
@ -163,6 +171,9 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
def get_visit_url(self): def get_visit_url(self):
return '/conference-visit/%s/'%self.id 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): def get_note_by_user(self, user_id):
note = self.note.filter(user__id=user_id) note = self.note.filter(user__id=user_id)
try: try:

@ -6,9 +6,9 @@ from django.shortcuts import get_object_or_404
from django.db.models import Sum from django.db.models import Sum
from expobanner.models import URL, BannerGroup, Banner, Paid, MainPage, Top from expobanner.models import URL, BannerGroup, Banner, Paid, MainPage, Top
from expobanner.forms import UrlCreateForm, BannerCreateGroupForm, BannerCreateForm, BannerGroupUpdateForm,\ 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 exposition.models import Exposition
from conference.models import Conference
class BannersControl(TemplateView): class BannersControl(TemplateView):
template_name = 'admin/expobanner/banners_control.html' template_name = 'admin/expobanner/banners_control.html'
@ -203,6 +203,8 @@ class PaidStat(DetailView):
return context return context
# ---------------------------------- # ----------------------------------
class MainList(ListView): class MainList(ListView):
model = Exposition model = Exposition
template_name = 'admin/expobanner/main_list.html' template_name = 'admin/expobanner/main_list.html'
@ -227,7 +229,6 @@ class MainUpdate(UpdateView):
template_name = 'admin/expobanner/default_form.html' template_name = 'admin/expobanner/default_form.html'
success_url = '/admin/expobanners/main/list/' success_url = '/admin/expobanners/main/list/'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(MainUpdate, self).get_context_data(**kwargs) context = super(MainUpdate, self).get_context_data(**kwargs)
obj = self.object obj = self.object
@ -235,6 +236,50 @@ class MainUpdate(UpdateView):
return context 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): def main_turn(request, pk, status):
main = get_object_or_404(MainPage, pk=pk) main = get_object_or_404(MainPage, pk=pk)
if status == 'on': if status == 'on':
@ -242,10 +287,11 @@ def main_turn(request, pk, status):
else: else:
main.public = False main.public = False
main.save() main.save()
return HttpResponseRedirect('/admin/expobanners/main/list/') return HttpResponseRedirect(request.META['HTTP_REFERER'])
from datetime import datetime from datetime import datetime
class MainStat(DetailView): class MainStat(DetailView):
model = MainPage model = MainPage
template_name = 'admin/expobanner/main_stat.html' 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/$', 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/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'), 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 django import forms
from expobanner.models import URL, BannerGroup, Banner, Paid, Top, MainPage from expobanner.models import URL, BannerGroup, Banner, Paid, Top, MainPage
from exposition.models import Exposition from exposition.models import Exposition
from conference.models import Conference
from country.models import Country from country.models import Country
from ckeditor.widgets import CKEditorWidget from ckeditor.widgets import CKEditorWidget
from theme.models import Theme, Tag from theme.models import Theme, Tag
@ -107,6 +108,7 @@ class PaidCreateForm(forms.ModelForm):
raise forms.ValidationError(u'Такой выставки не существует') raise forms.ValidationError(u'Такой выставки не существует')
return expo return expo
class MainCreateForm(forms.ModelForm): class MainCreateForm(forms.ModelForm):
verbose = u'Добавить выставку на главную' verbose = u'Добавить выставку на главную'
exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput()) exposition = forms.CharField(label=u'Выставка', widget=forms.HiddenInput())
@ -137,6 +139,36 @@ class MainCreateForm(forms.ModelForm):
return expo 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): class PaidUpdateForm(forms.ModelForm):
tickets = forms.URLField(label=u'Линк на билеты') tickets = forms.URLField(label=u'Линк на билеты')
participation = forms.URLField(label=u'Линк на участие') participation = forms.URLField(label=u'Линк на участие')

@ -297,7 +297,13 @@ class MainPage(models.Model, StatMixin):
try: try:
return self.exposition_set.all()[0] return self.exposition_set.all()[0]
except IndexError: 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): def generatePassword(length=5):

@ -178,6 +178,13 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return list(qs) 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): def get_parent(self):
return {} return {}
def get_absolute_url(self): def get_absolute_url(self):
@ -285,6 +292,9 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def get_visit_url(self): def get_visit_url(self):
return '/exposition-visit/%s/'%self.id return '/exposition-visit/%s/'%self.id
def get_note_url(self):
return '/expo/add-note/%s/'%self.url
def get_timetables_days(self): def get_timetables_days(self):
tables = self.business_program.all() tables = self.business_program.all()
days = [] days = []
@ -306,12 +316,6 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def theme_ids(self): def theme_ids(self):
return [item['id'] for item in self.theme.all().values('id')] 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): def get_top_link(self):
if self.top: if self.top:
return self.top.link.get_click_link() return self.top.link.get_click_link()

@ -5,11 +5,6 @@ from service.models import Service
class ExpoMixin(object): class ExpoMixin(object):
# def get_index_text(self):
# names = [tr.name for tr in self.translations.all()]
# return names
def get_logo(self): def get_logo(self):
logo = self.files.filter(purpose='logo') logo = self.files.filter(purpose='logo')
@ -34,6 +29,12 @@ class EventMixin(object):
url = '%s%s/'%(self.get_catalog_url(), self.url) url = '%s%s/'%(self.get_catalog_url(), self.url)
return 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): def get_paid_catalog_url(self):
return self.paid_new.catalog.get_click_link() return self.paid_new.catalog.get_click_link()
@ -45,12 +46,6 @@ class EventMixin(object):
def get_logo(self): def get_logo(self):
return self.logo return self.logo
"""
logo = self.files.filter(purpose='logo')
if logo:
return logo[0]
return logo
"""
def get_preview(self): def get_preview(self):

@ -39,6 +39,22 @@ class ExpoManager(TranslationManager):
return result 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): class CityManager(TranslationManager):

@ -1,22 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.core.context_processors import csrf
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.template import RequestContext from django.template import RequestContext
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.conf import settings from django.conf import settings
from exposition.models import Exposition from django.utils.translation import get_language
from theme.models import Theme from functions.cache_mixin import JitterCacheMixin
from news.models import News from functions.forms import ThemeSearch
from article.models import Article from functions.search_forms import ExpositionSearchForm
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 accounts.forms import RegistrationCompleteForm, SocialRegistrationCompleteForm from accounts.forms import RegistrationCompleteForm, SocialRegistrationCompleteForm
from meta.models import SeoText 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_): def clear_slashes(str_):
@ -73,11 +69,13 @@ def error404(request):
class MainPageView(JitterCacheMixin, TemplateView): class MainPageView(JitterCacheMixin, TemplateView):
cache_range = settings.CACHE_RANGE cache_range = settings.CACHE_RANGE
template_name = 'index.html' template_name = 'client/index.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(MainPageView, self).get_context_data(**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) events = sorted(ev, key=lambda x: x.main.position)
# update main_page counter # update main_page counter
for event in events: for event in events:

@ -117,28 +117,61 @@ def get_city(request):
return HttpResponse('error') return HttpResponse('error')
class ServiceControlList(ListView): from django.shortcuts import get_object_or_404
model = Service from django.views.generic import UpdateView, ListView, DeleteView
template_name = 'admin/service/control_list.html' from .forms import LinkedServiceForm
paginate_by = 20 from .models import LinkedService
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 LinkedServiceUpdateView(UpdateView):
class ServiceControl(FormMixin, DetailView): form_class = LinkedServiceForm
form_class = ServiceControlForm model = LinkedService
template_name = 'admin/service/control.html' template_name = "admin/service/linked_service.html"
model = Service success_url = "/admin/service/control/all/"
def get_object(self, queryset=None):
def get_form(self, form_class): url = self.kwargs['url']
obj = self.object service = get_object_or_404(Service, url=url)
data = obj.get_current_state() obj = LinkedService.objects.get(service=service)
return obj
return form_class(data)
def get_initial(self):
def get_context_data(self, **kwargs): types = {0:[], 1:['expo'], 2:['conference'], 3:['expo', 'conference']}
context = super(ServiceControl, self).get_context_data(**kwargs) initial = {
context['form'] = self.get_form(self.form_class) 'expositions': ",".join("%s:%s"%(item.id, item.name) for item in self.object.expositions.all()),
return context '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 django.conf.urls import patterns, include, url
from views import CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \ from views import CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \
ParticipationListView, RemoteListView,TicketsListView ParticipationListView, RemoteListView,TicketsListView
from service.admin import ServiceControlList, ServiceControl from service.admin import LinkedServiceList, LinkedServiceUpdateView, LinkedServiceDeleteView
urlpatterns = patterns('service.admin', 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'^add.*/$', 'service_add'),
url(r'^delete/(?P<url>.*)/$', 'service_delete'), url(r'^delete/(?P<url>.*)/$', 'service_delete'),
url(r'^change/(?P<url>.*)/$', 'service_change'), 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/participation/$', ParticipationListView.as_view()),
url(r'order/remote/$', RemoteListView.as_view()), url(r'order/remote/$', RemoteListView.as_view()),
url(r'order/tickets/$', TicketsListView.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 #ajax
url(r'^get_city/$', 'get_city'), 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 exposition.models import Exposition
from conference.models import Conference 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): from .models import LinkedService
super(ServiceControlForm, self).__init__(*args, **kwargs) from django.db.models.query import EmptyQuerySet
self.fields['event_type'] = forms.MultipleChoiceField(required=False, label = 'Тип события',
widget=forms.CheckboxSelectMultiple(),
choices=[(item['service_bit'], item['verbose']) class LinkedServiceForm(forms.ModelForm):
for item in self.event]) 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): def get_price(self):
pr = self.price 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 django.db.models.signals import post_save
from functions.signal_handlers import post_save_handler from functions.signal_handlers import post_save_handler
@ -198,4 +144,54 @@ class CallBack(models.Model):
viewed = models.DateTimeField(null=True, blank=True) viewed = models.DateTimeField(null=True, blank=True)
class Meta: 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> <span class="help-inline">{{ form.publish_date.errors }}</span>
</div> </div>
</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 #} {# theme #}
<div class="control-group {% if form.theme.errors %}error{% endif %}"> <div class="control-group {% if form.theme.errors %}error{% endif %}">
<label class="control-label"><b>{{ form.theme.label }}:</b></label> <label class="control-label"><b>{{ form.theme.label }}:</b></label>

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

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

@ -51,7 +51,7 @@
<div class="box span8"> <div class="box span8">
<div class="box-header well"> <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>
<div class="box-content"> <div class="box-content">
{% for field in form %} {% for field in form %}

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

@ -40,8 +40,10 @@
<li><a href="/admin/country/all">Страна</a></li> <li><a href="/admin/country/all">Страна</a></li>
<li><a href="/admin/city/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/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/theme/tag/all">Теги</a></li>
<li><a href="/admin/service/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/settings/main-page/">Главная страница</a></li>
<li><a href="/admin/meta/all/">Мета</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/paid/list/">Платные выставки</a></li>
<li><a href="/admin/expobanners/top/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/list/">Выставки на главной</a></li>
<li><a href="/admin/expobanners/main/conf/list/">Конференции на главной</a></li>
</ul> </ul>
</li> </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' %} {% include 'admin/forms/multilang.html' %}
{% endwith %} {% endwith %}
{# url #} {# 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> <label class="control-label">{{ form.url.label }}:</label>
<div class="controls"> <div class="controls">
{{ form.url }} {{ 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 %} {% include 'client/includes/article/article_logo.html' with obj=object %}
<h1>{{ object.main_title }}</h1> <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 %} {% if request.user.is_admin %}
<a target="_blank" class="button green " href="/admin/article/blog/{{ object.slug }}/">{% trans 'изменить' %}</a> <a target="_blank" class="button green " href="/admin/article/blog/{{ object.slug }}/">{% trans 'изменить' %}</a>
{% endif %} {% endif %}
@ -54,7 +54,7 @@
<a href="{{ blog.get_permanent_url }}" title="">{% include 'includes/show_logo.html' with obj=blog %}</a> <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> <h3><a href="{{ blog.get_permanent_url }}" title="">{{ blog.main_title }}</a></h3>
<p>{{ blog.preview }}</p> <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>
</div> </div>
{% endfor %} {% endfor %}

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

@ -2,7 +2,7 @@
<div class="ied-text" style="text-align: justify"> <div class="ied-text" style="text-align: justify">
{% blocktrans with name=conf.name%} {% blocktrans with name=conf.name%}
<p>Конференция {{name}} проходит {% endblocktrans %}{% include 'client/includes/show_date_block.html' with obj=conf %} <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}}. в городе {{city}}, {{country}}.
Посмотреть, как проехать в место проведения конференции, можно на сайте конгрессной площадки. Посмотреть, как проехать в место проведения конференции, можно на сайте конгрессной площадки.
Деловая программа {{name}} разбита на секции по дням и размещается на сайте мероприятия с подробным списком Деловая программа {{name}} разбита на секции по дням и размещается на сайте мероприятия с подробным списком

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

@ -36,7 +36,7 @@
<div class="re-buttons"> <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> <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 %}"> <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"> <div class="note-overlay">
<form action=""> <form action="">
<textarea name="note_text" class="note-text"> {{ note }}</textarea> <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>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}> <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 /> <hr />

@ -58,7 +58,7 @@
</div> </div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}> <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 /> <hr />

@ -51,7 +51,7 @@
</div> </div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}> <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 /> <hr />

@ -53,7 +53,7 @@
</div> </div>
<div class="rq-form service-page" {% if form.errors %}style="display:block"{% endif %}> <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 /> <hr />

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

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

@ -93,7 +93,12 @@ if (EXPO.common){
$.fancybox.close(true); $.fancybox.close(true);
$.fancybox('#'+EXPO.common.opt.successRegisterId); $.fancybox('#'+EXPO.common.opt.successRegisterId);
}else{ }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(); window.location.reload();
} }
}else{ }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.http import HttpResponseRedirect, HttpResponse
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.conf import settings from django.conf import settings
from django.forms.formsets import BaseFormSet, formset_factory from django.views.generic import CreateView, UpdateView, DeleteView
from django.forms.models import modelformset_factory
from django.contrib.contenttypes.models import ContentType
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
#forms and models #forms and models
from forms import ThemeForm, TagForm, ThemeDeleteForm, TagDeleteForm, TagFilterForm, ThemeFilterForm from forms import ThemeForm, TagForm, ThemeDeleteForm, TagDeleteForm, TagFilterForm, ThemeFilterForm
from models import Theme, Tag from models import Theme, Tag, ThemeBlog
#custom views #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.views_help import get_referer
from functions.admin_views import AdminListView from functions.admin_views import AdminListView
@ -170,4 +168,70 @@ class ThemeListView(AdminListView):
class TagListView(AdminListView): class TagListView(AdminListView):
template_name = 'admin/theme/tag_list.html' template_name = 'admin/theme/tag_list.html'
form_class = TagFilterForm 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 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from admin import TagListView, ThemeListView from admin import TagListView, ThemeListView
from .admin import ThemeBlogCreateView, ThemeBlogUpdateView, ThemeBlogDeleteView, ThemeBlogListView
urlpatterns = patterns('theme.admin', urlpatterns = patterns('theme.admin',
url(r'^theme/add.*/$', 'theme_add'), url(r'^theme/add.*/$', 'theme_add'),
url(r'^tag/add.*/$', 'tag_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'^theme/delete/(?P<theme_id>\d+)/$', 'theme_delete'),
url(r'^tag/delete/(?P<tag_id>\d+)/$', 'tag_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'^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'^tag/change/(?P<tag_id>\d+).*/$', 'tag_change'),
url(r'^theme/copy/(?P<theme_id>\d+).*/$', 'theme_copy'), url(r'^theme/copy/(?P<theme_id>\d+).*/$', 'theme_copy'),
url(r'^tag/copy/(?P<tag_id>\d+).*/$', 'tag_copy'), url(r'^tag/copy/(?P<tag_id>\d+).*/$', 'tag_copy'),
#url(r'^theme/all/$', 'theme_all'), #url(r'^theme/all/$', 'theme_all'),
#url(r'^tag/all/$', 'tag_all'), #url(r'^tag/all/$', 'tag_all'),
url(r'^theme/all/$', ThemeListView.as_view()), 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/all/$', TagListView.as_view()),
url(r'^tag/search/$', 'search_tag'), url(r'^tag/search/$', 'search_tag'),
url(r'^tag/search-without-theme/$', 'search2'), url(r'^tag/search-without-theme/$', 'search2'),

@ -143,4 +143,49 @@ class ThemeFilterForm(AdminFilterForm):
class TagFilterForm(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 = {} parent = {}
return 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 from django.db import IntegrityError
class Tag(TranslatableModel): class Tag(TranslatableModel):
""" """
@ -249,6 +273,7 @@ def pre_save_handler(sender, **kwargs):
pre_save.connect(pre_save_handler, sender=Tag) pre_save.connect(pre_save_handler, sender=Tag)
post_save.connect(post_save_handler, sender=Theme) post_save.connect(post_save_handler, sender=Theme)
post_save.connect(post_save_handler, sender=ThemeBlog)
post_save.connect(post_save_handler, sender=Tag) post_save.connect(post_save_handler, sender=Tag)

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

Loading…
Cancel
Save