Search. Import. Visit

remotes/origin/1203
Kotiuk Nazarii 11 years ago
parent a4a2348888
commit d4563800ea
  1. 7
      city/models.py
  2. 34
      city/search_indexes.py
  3. 2
      conference/admin.py
  4. 7
      conference/forms.py
  5. 10
      conference/search_indexes.py
  6. 2
      conference/urls.py
  7. 8
      conference/views.py
  8. 7
      country/manager.py
  9. 12
      country/models.py
  10. 62
      country/search_indexes.py
  11. 2
      exposition/admin.py
  12. 15
      exposition/forms.py
  13. 1
      exposition/models.py
  14. 10
      exposition/search_indexes.py
  15. 1
      exposition/urls.py
  16. 7
      exposition/views.py
  17. 7
      functions/model_mixin.py
  18. 2
      functions/search_forms.py
  19. 53
      import_xls/admin.py
  20. 10
      import_xls/admin_urls.py
  21. 30
      import_xls/import_forms.py
  22. 77
      import_xls/models.py
  23. 19
      import_xls/utils.py
  24. 2
      proj/admin_urls.py
  25. 1
      proj/settings.py
  26. 4
      settings/templatetags/template_filters.py
  27. 31
      settings/views.py
  28. 4
      static/custom_js/main.js
  29. 9
      templates/admin/base.html
  30. 8
      templates/admin/conference/conference.html
  31. 40
      templates/admin/exposition/exposition.html
  32. 47
      templates/admin/import templates/log.html
  33. 15
      templates/admin/import templates/log_delete.html
  34. 1
      templates/client/exposition/exposition_detail.html
  35. 13
      templates/client/includes/conference/conference_object.html
  36. 14
      templates/client/includes/exposition/exposition_object.html
  37. 6
      templates/client/includes/exposition/exposition_services.html
  38. 1
      templates/client/includes/services.html
  39. 2
      templates/client/search/indexes/city/city_text.txt
  40. 1
      templates/client/search/indexes/country/area_text.txt
  41. 1
      templates/client/search/indexes/country/country_text.txt
  42. 11
      theme/models.py
  43. 2
      theme/search_indexes.py

@ -2,6 +2,7 @@
from datetime import date from datetime import date
from django.db import models from django.db import models
from django.db.models.signals import post_save, pre_save from django.db.models.signals import post_save, pre_save
from django.utils import translation
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from bitfield import BitField from bitfield import BitField
from sorl.thumbnail import ImageField from sorl.thumbnail import ImageField
@ -116,6 +117,12 @@ class City(TranslatableModel):
def get_sub_categories(self): def get_sub_categories(self):
return [] return []
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names

@ -1,18 +1,36 @@
# -*- coding: utf-8 -*-
from django.utils import translation
from haystack import indexes from haystack import indexes
from models import City from models import City
from functions.search_mixin import ExpoSearchMixin
"""
class CityIndex(indexes.SearchIndex, indexes.Indexable): class CountryIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True, use_template=True)
translations = indexes.MultiValueField() url = indexes.CharField()
#name = indexes.CharField(model_attr='translations__name') content_auto = indexes.EdgeNgramField()
form_name = indexes.CharField()
# translated fields
name_en = indexes.CharField()
name_ru = indexes.CharField()
catalog_name_en = indexes.CharField()
catalog_name_ru = indexes.CharField()
def prepare_form_name(self, obj):
return 'ci'
def prepare_catalog_name_en(self, obj):
return u'Cities'
def prepare_translations(self, obj): def prepare_catalog_name_ru(self, obj):
return [tr.name for tr in obj.translations.all()] return u'Города'
def get_model(self): def get_model(self):
return City return City
def index_queryset(self, using=None): def index_queryset(self, using=None):
return self.get_model().objects.filter()
""" return self.get_model().used.all()
def get_updated_field(self):
return 'modified'

@ -239,7 +239,7 @@ class ConferenceView(AdminView):
'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,
'discount': obj.discount,'canceled': obj.canceled, 'moved': obj.moved, 'discount': obj.discount,'canceled': obj.canceled, 'moved': obj.moved,
'visitors': obj.visitors, 'members': obj.members, 'logo': obj.logo, 'visitors': obj.visitors, 'members': obj.members, 'logo': obj.logo,
'audience':[item for item, bool in obj.audience if bool==True], 'audience':[item for item, bool in obj.audience if bool==True], 'org': obj.org,
'quality_label': [item for item, bool in obj.quality_label if bool==True]} 'quality_label': [item for item, bool in obj.quality_label if bool==True]}
if obj.place: if obj.place:

@ -47,9 +47,9 @@ class ConferenceCreateForm(forms.Form):
data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y']) data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label='Logo', required=False) logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False, #organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()]) # choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
org = forms.CharField(required=False, label=u'Организатор')
country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()]) country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()])
theme = forms.MultipleChoiceField(label='Тематики', theme = forms.MultipleChoiceField(label='Тематики',
choices=[(item.id, item.name) for item in Theme.objects.language().all()]) choices=[(item.id, item.name) for item in Theme.objects.language().all()])
@ -140,6 +140,7 @@ class ConferenceCreateForm(forms.Form):
if data.get('logo'): if data.get('logo'):
conference.logo = data['logo'] conference.logo = data['logo']
conference.org = data['org']
conference.data_begin = data['data_begin'] conference.data_begin = data['data_begin']
conference.data_end = data['data_end'] conference.data_end = data['data_end']
conference.link = data['link'] conference.link = data['link']

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from haystack import indexes from haystack import indexes
from models import Conference from models import Conference
from functions.search_mixin import ExpoSearchMixin
class ConferenceIndex(indexes.SearchIndex, indexes.Indexable): class ConferenceIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True) text = indexes.CharField(document=True, use_template=True)
where = indexes.MultiValueField() where = indexes.MultiValueField()
url = indexes.CharField() url = indexes.CharField()
@ -31,13 +32,6 @@ class ConferenceIndex(indexes.SearchIndex, indexes.Indexable):
def prepare_catalog_name_ru(self, obj): def prepare_catalog_name_ru(self, obj):
return u'Конференции' return u'Конференции'
def prepare_where(self, obj):
country = [tr.name for tr in obj.country.translations.all()]
city = [tr.name for tr in obj.city.translations.all()]
return country + city
def get_model(self): def get_model(self):
return Conference return Conference

@ -66,6 +66,8 @@ urlpatterns = patterns('',
url(r'conference/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ConferenceMembers.as_view()), url(r'conference/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ConferenceMembers.as_view()),
url(r'conference/(?P<slug>.*)/members/$', ConferenceMembers.as_view()), url(r'conference/(?P<slug>.*)/members/$', ConferenceMembers.as_view()),
url(r'^conference/(?P<slug>.*)/service/thanks/', ConferenceThankView.as_view()), url(r'^conference/(?P<slug>.*)/service/thanks/', ConferenceThankView.as_view()),
url(r'^conference/(?P<slug>.*)/service/visit/', 'conference.views.visit_redirect'),
url(r'conference/(?P<slug>.*)/service/(?P<service_url>.*)/', ConferenceServiceView.as_view()), url(r'conference/(?P<slug>.*)/service/(?P<service_url>.*)/', ConferenceServiceView.as_view()),

@ -2,7 +2,7 @@
import json import json
import datetime import datetime
from django.conf import settings from django.conf import settings
from django.http import HttpResponse, Http404, HttpResponseRedirect from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponsePermanentRedirect
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
@ -287,6 +287,12 @@ class ConferenceThankView(MetadataMixin, DetailView):
slug_field = 'url' slug_field = 'url'
template_name = 'client/service/thank_u_page.html' template_name = 'client/service/thank_u_page.html'
def visit_redirect(request, slug):
obj = get_object_or_404(Conference, url=slug)
redirect = obj.get_permanent_url()
return HttpResponsePermanentRedirect(redirect)
class ConferenceServiceView(FormMixin, DetailView): class ConferenceServiceView(FormMixin, DetailView):
model = Conference model = Conference
slug_field = 'url' slug_field = 'url'

@ -93,6 +93,13 @@ class CountryManager(TranslationManager):
cache.set(key, countries, self.cache_time) cache.set(key, countries, self.cache_time)
return countries return countries
def countries_for_search(self):
lang = translation.get_language()
qs = super(CountryManager, self).select_related('exposition_country').\
filter(exposition_country__country__isnull=False, translations__language_code=lang, )\
.order_by('translations__name').distinct()
return qs
class AreaManager(TranslationManager): class AreaManager(TranslationManager):
def all_sorted(self): def all_sorted(self):

@ -55,6 +55,12 @@ class Area(TranslatableModel):
parent = {} parent = {}
return parent return parent
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names
class Country(TranslatableModel): class Country(TranslatableModel):
""" """
@ -161,6 +167,12 @@ class Country(TranslatableModel):
parent = {'text' : self.area.name, 'id': self.area.id, 'name': 'area'} parent = {'text' : self.area.name, 'id': self.area.id, 'name': 'area'}
return parent return parent
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
return names
pre_save.connect(pre_save_handler, sender=Country) pre_save.connect(pre_save_handler, sender=Country)

@ -0,0 +1,62 @@
# -*- coding: utf-8 -*-
from django.utils import translation
from haystack import indexes
from models import Country, Area
from functions.search_mixin import ExpoSearchMixin
class CountryIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True)
url = indexes.CharField()
content_auto = indexes.EdgeNgramField()
form_name = indexes.CharField()
# translated fields
name_en = indexes.CharField()
name_ru = indexes.CharField()
catalog_name_en = indexes.CharField()
catalog_name_ru = indexes.CharField()
def prepare_form_name(self, obj):
return 'co'
def prepare_catalog_name_en(self, obj):
return u'Countries'
def prepare_catalog_name_ru(self, obj):
return u'Страны'
def get_model(self):
return Country
def index_queryset(self, using=None):
return self.get_model().objects.countries_for_search()
def get_updated_field(self):
return 'modified'
class AreaIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
text = indexes.CharField(document=True, use_template=True)
content_auto = indexes.EdgeNgramField()
form_name = indexes.CharField()
# translated fields
name_en = indexes.CharField()
name_ru = indexes.CharField()
catalog_name_en = indexes.CharField()
catalog_name_ru = indexes.CharField()
def prepare_form_name(self, obj):
return 'area'
def prepare_catalog_name_en(self, obj):
return u'Areas'
def prepare_catalog_name_ru(self, obj):
return u'Регионы'
def get_model(self):
return Area
def index_queryset(self, using=None):
return self.get_model().objects.filter()

@ -277,7 +277,7 @@ class ExpositionView(AdminView):
'min_stand_size':obj.min_stand_size, 'application_deadline':obj.application_deadline, 'min_stand_size':obj.min_stand_size, 'application_deadline':obj.application_deadline,
'min_open_area':obj.min_open_area, 'max_open_area':obj.max_open_area, 'min_open_area':obj.min_open_area, 'max_open_area':obj.max_open_area,
'registration_payment':obj.registration_payment, 'exposition_id':obj.id, 'registration_payment':obj.registration_payment, 'exposition_id':obj.id,
'registration_link': obj.registration_link, 'registration_link': obj.registration_link, 'org': obj.org,
'expohit': obj.expohit, 'discount': obj.discount, 'expohit': obj.expohit, 'discount': obj.discount,
'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo, 'canceled': obj.canceled, 'moved': obj.moved, 'logo': obj.logo,
'visitors': obj.visitors, 'members': obj.members, 'visitors': obj.visitors, 'members': obj.members,

@ -49,11 +49,12 @@ class ExpositionCreateForm(forms.Form):
data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y']) data_end = forms.DateField(label=u'Дата окончания', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
logo = forms.ImageField(label='Logo', required=False) logo = forms.ImageField(label='Logo', required=False)
organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False, #organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
choices=[(item.id, item.name) for item in Organiser.objects.language().all()]) # choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
org = forms.CharField(required=False, label=u'Организатор')
company = forms.MultipleChoiceField(label=u'Компании', required=False, #company = forms.MultipleChoiceField(label=u'Компании', required=False,
choices=[(item.id, item.name) for item in Company.objects.language().all()] ) # choices=[(item.id, item.name) for item in Company.objects.language().all()] )
country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()]) country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()])
theme = forms.MultipleChoiceField(label='Тематики', theme = forms.MultipleChoiceField(label='Тематики',
choices=[(item.id, item.name) for item in Theme.objects.language().all()]) choices=[(item.id, item.name) for item in Theme.objects.language().all()])
@ -62,7 +63,6 @@ class ExpositionCreateForm(forms.Form):
#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())
tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False) tag = forms.CharField(label=u'Теги', widget=forms.HiddenInput(), required=False)
#tag = forms.MultipleChoiceField(label=u'Теги', required=False)
periodic = forms.ChoiceField(label=u'Периодичность', choices=PERIODIC, required=False) periodic = forms.ChoiceField(label=u'Периодичность', choices=PERIODIC, required=False)
audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False) audience = forms.MultipleChoiceField(label=u'Аудитория', choices=public, initial='', required=False)
@ -169,7 +169,7 @@ class ExpositionCreateForm(forms.Form):
exposition.theme.clear() exposition.theme.clear()
exposition.tag.clear() exposition.tag.clear()
exposition.organiser.clear() exposition.organiser.clear()
exposition.company.clear() #exposition.company.clear()
#simple fields #simple fields
if not getattr(exposition, 'url'): if not getattr(exposition, 'url'):
@ -177,6 +177,7 @@ class ExpositionCreateForm(forms.Form):
if data.get('logo'): if data.get('logo'):
exposition.logo = data['logo'] exposition.logo = data['logo']
exposition.org = data['org']
exposition.data_begin = data['data_begin'] exposition.data_begin = data['data_begin']
exposition.data_end = data['data_end'] exposition.data_end = data['data_end']
exposition.periodic = data['periodic'] exposition.periodic = data['periodic']
@ -236,7 +237,7 @@ class ExpositionCreateForm(forms.Form):
exposition.theme.add(*data['theme']) exposition.theme.add(*data['theme'])
exposition.tag.add(*Tag.objects.filter(id__in=data['tag'])) exposition.tag.add(*Tag.objects.filter(id__in=data['tag']))
exposition.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', []))) exposition.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', [])))
exposition.company.add(*Company.objects.filter(id__in=data.get('company', []))) #exposition.company.add(*Company.objects.filter(id__in=data.get('company', [])))
exposition.save() exposition.save()

@ -72,6 +72,7 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
organiser = models.ManyToManyField('organiser.Organiser', verbose_name='Организатор', organiser = models.ManyToManyField('organiser.Organiser', verbose_name='Организатор',
blank=True, null=True, related_name='exposition_organisers') blank=True, null=True, related_name='exposition_organisers')
org = models.CharField(max_length=255, blank=True, null=True) org = models.CharField(max_length=255, blank=True, null=True)
place_alt = models.CharField(max_length=255, blank=True, null=True)
company = models.ManyToManyField('company.Company', verbose_name='Компании', company = models.ManyToManyField('company.Company', verbose_name='Компании',
blank=True, null=True, related_name='exposition_companies') blank=True, null=True, related_name='exposition_companies')
users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки', users = models.ManyToManyField('accounts.User', verbose_name='Посетители выставки',

@ -40,15 +40,5 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
return self.get_model().objects.filter(is_published=True) return self.get_model().objects.filter(is_published=True)
def get_name(self):
return 123
lang = translation.get_language()
if lang == 'ru':
return self.name_ru
elif lang=='en':
return self.name_en
else:
return self.name_ru
def get_updated_field(self): def get_updated_field(self):
return 'modified' return 'modified'

@ -72,6 +72,7 @@ urlpatterns = patterns('',
url(r'^expo/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ExpoMembers.as_view(), {'meta_id':63}), url(r'^expo/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ExpoMembers.as_view(), {'meta_id':63}),
url(r'^expo/(?P<slug>.*)/members/$', ExpoMembers.as_view(), {'meta_id':63}), url(r'^expo/(?P<slug>.*)/members/$', ExpoMembers.as_view(), {'meta_id':63}),
url(r'^expo/(?P<slug>.*)/service/thanks/', ExpositionThankView.as_view()), url(r'^expo/(?P<slug>.*)/service/thanks/', ExpositionThankView.as_view()),
url(r'^expo/(?P<slug>.*)/service/visit/', 'exposition.views.visit_redirect'),
url(r'^expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()), url(r'^expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()),
# expo list # expo list
url(r'^expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':4}), url(r'^expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view(), {'meta_id':4}),

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json import json
import datetime import datetime
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse, HttpResponsePermanentRedirect
from django.contrib import messages from django.contrib import messages
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.conf import settings from django.conf import settings
@ -182,6 +182,11 @@ class ExpositionThankView(MetadataMixin, DetailView):
slug_field = 'url' slug_field = 'url'
template_name = 'client/service/thank_u_page.html' template_name = 'client/service/thank_u_page.html'
def visit_redirect(request, slug):
obj = get_object_or_404(Exposition, url=slug)
redirect = obj.get_permanent_url() + 'price/'
return HttpResponsePermanentRedirect(redirect)
class ExpositionServiceView(MetadataMixin, FormMixin, DetailView): class ExpositionServiceView(MetadataMixin, FormMixin, DetailView):
model = Exposition model = Exposition
slug_field = 'url' slug_field = 'url'

@ -32,8 +32,11 @@ 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 org_split(self):
if self.org:
return self.org.split(';')
else:
return []
def get_logo(self): def get_logo(self):
return self.logo return self.logo

@ -279,7 +279,7 @@ class ExpositionSearchForm(AbstactSearchForm):
area = self.cleaned_data.get('area') area = self.cleaned_data.get('area')
sqs = SearchQuerySet().models(Exposition).all() sqs = SearchQuerySet().models(Exposition, Conference).all()
if fr: if fr:
sqs = sqs.filter(data_begin__gte=fr) sqs = sqs.filter(data_begin__gte=fr)

@ -13,8 +13,10 @@ from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, Import
from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\ from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\
ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\ ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\
ExportCityForm ExportCityForm
from django.views.generic import FormView from django.views.generic import FormView, ListView, DeleteView
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.shortcuts import get_object_or_404
def xls_to_response(xls, fname): def xls_to_response(xls, fname):
response = HttpResponse(mimetype="application/ms-excel") response = HttpResponse(mimetype="application/ms-excel")
@ -97,20 +99,23 @@ class ExportCity(ExportView):
from exposition.models import Exposition from import_xls.models import Log
class ImportEvent(FormView): class ImportEvent(FormView):
form_class = ImportEventForm form_class = ImportEventForm
success_url = '/admin/import-event/' success_url = '/admin/import-event/'
template_name = 'admin/import templates/import_event.html' template_name = 'admin/import templates/import_event.html'
def form_valid(self, form): def form_valid(self, form):
errors = form.save_file_debug() errors = form.save_file_debug()
messages.success(self.request, 'Success') return HttpResponseRedirect('/admin/import/log/')
context = self.get_context_data()
context['import_errors'] = errors #messages.success(self.request, 'Success')
context['form'] = form
return render_to_response(self.template_name, context) #context = self.get_context_data()
#context['import_errors'] = errors
#context['form'] = form
#return render_to_response(self.template_name, context)
#return super(ImportEvent, self).form_valid(form)
class ImportTheme(ImportView): class ImportTheme(ImportView):
form_class = ImportThemeForm form_class = ImportThemeForm
@ -135,4 +140,34 @@ class ImportPlaceConference(ImportView):
class ExportEvent(ExportView): class ExportEvent(ExportView):
form_class = ExportEventForm form_class = ExportEventForm
template_name = 'export_event.html' template_name = 'export_event.html'
success_url = '/admin/export-event' success_url = '/admin/export-event'
class LogList(ListView):
model = Log
paginate_by = settings.ADMIN_PAGINATION
template_name = 'admin/import templates/log.html'
class LogDelete(DeleteView):
model = Log
success_url = '/admin/import/log/'
template_name = 'admin/import templates/log_delete.html'
def log_file(request, log_id):
log = get_object_or_404(Log, id=log_id)
response = HttpResponse()
response['content-type'] = 'application/x-executable'
filename = 'import_%s_log.txt'%str(log.id)
response['content-disposition'] = 'attachment;filename=%s'%filename
response['X-Accel-Redirect'] = log.log.url
return response
def work_file(request, log_id):
log = get_object_or_404(Log, id=log_id)
response = HttpResponse()
response['content-type'] = 'application/x-executable'
filename = 'import_%s_file.xls'%str(log.id)
response['content-disposition'] = 'attachment;filename=%s'%filename
response['X-Accel-Redirect'] = log.work_file.url
return response

@ -2,8 +2,11 @@
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference
from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\ from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\
ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList
from import_xls.admin import LogDelete
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^import-event/$', ImportEvent.as_view()), url(r'^import-event/$', ImportEvent.as_view()),
@ -23,5 +26,8 @@ urlpatterns = patterns('',
url(r'^export-company/$', ExportCompany.as_view()), url(r'^export-company/$', ExportCompany.as_view()),
url(r'^export-blog/$', ExportBlog.as_view()), url(r'^export-blog/$', ExportBlog.as_view()),
url(r'^export-city/$', ExportCity.as_view()), url(r'^export-city/$', ExportCity.as_view()),
url(r'^import/log/$', LogList.as_view()),
url(r'^import/log/delete/(?P<pk>.*)/$', LogDelete.as_view()),
url(r'^log/log/(?P<log_id>.*)/$', 'import_xls.admin.log_file'),
url(r'^log/work_file/(?P<log_id>.*)/$', 'import_xls.admin.work_file'),
) )

@ -246,6 +246,15 @@ typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправи
'(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'} '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'}
# event # event
import time
def logcall(f, msg):
with open(f.file.name, 'a') as logfile:
logfile.write(msg.encode('utf8'))
from import_xls.models import Log
class ImportEventForm(ImportForm): class ImportEventForm(ImportForm):
""" """
extended form for importing one type of event extended form for importing one type of event
@ -270,10 +279,12 @@ class ImportEventForm(ImportForm):
labels = [label for label in row_list[0]] labels = [label for label in row_list[0]]
errors = [] errors = []
log = Log.custom.create_log_name(f)
for row_number, row in enumerate(row_list): for row_number, row in enumerate(row_list):
if row_number == 0: if row_number == 0:
continue continue
log_msg = u'[%s] %s: '%(str(row_number), row[2])
if row[0] != '': if row[0] != '':
# in first column id # in first column id
try: try:
@ -305,7 +316,8 @@ class ImportEventForm(ImportForm):
if setting.get('method'): if setting.get('method'):
# this cell contains data that must be written after creating object # this cell contains data that must be written after creating object
if cell != "": if cell != "":
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')}) methods.append({'func': setting['func'], 'value': cell,
'purpose': setting.get('purpose'), 'field': label})
continue continue
field_name = setting['field'] field_name = setting['field']
@ -316,7 +328,7 @@ class ImportEventForm(ImportForm):
extra_value = setting.get('extra_values') extra_value = setting.get('extra_values')
if extra_value is not None: if extra_value is not None:
# if setting has extra value then # if setting has extra value then
# it is some field like city, theme, tag # it is some field like city, tag
# that has relation and can be created # that has relation and can be created
# in function we add language(need for relation fields) # in function we add language(need for relation fields)
@ -332,8 +344,8 @@ class ImportEventForm(ImportForm):
else: else:
value = func(cell) value = func(cell)
if field_name != 'place':
if field_name != 'place':
try: try:
setattr(obj, field_name, value) setattr(obj, field_name, value)
except ValueError: except ValueError:
@ -351,15 +363,17 @@ class ImportEventForm(ImportForm):
obj.is_published = True obj.is_published = True
try: try:
obj.save() obj.save()
except IntegrityError, e: except IntegrityError, e:
error = str(e) error = str(e)
if typical_errors.get(error): if typical_errors.get(error):
error = typical_errors[error] error = typical_errors[error]
if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'): if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'):
error = u'Событие с таким названием или урлом уже существует' error = u'Событие с таким названием или урлом уже существует'
errors.append([obj.name, error]) errors.append([obj.name, error])
log_msg += error
logcall(log.log, log_msg + '\n')
continue continue
for method in methods: for method in methods:
@ -368,12 +382,14 @@ class ImportEventForm(ImportForm):
try: try:
func(obj, method['value'], method['purpose']) func(obj, method['value'], method['purpose'])
except: except:
log_msg += '(%s: Ошибка);'%method['field']
continue continue
else: else:
func(obj, method['value']) msg = func(obj, method['value'])
if msg:
#------------- log_msg += '(%s: %s);'%(method['field'], msg)
logcall(log.log, log_msg + '\n')
return errors return errors
def save_file(self): def save_file(self):

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
from django.db import models
from django.conf import settings
from django.db.models.fields.files import FieldFile
from django.db.models.signals import pre_delete
def get_doc_dir(instance, filename):
from pytils import translit
return u'import_xls/import/%s' %translit.translify(filename)
def file_cleanup(sender, instance, *args, **kwargs):
'''
Deletes the file(s) associated with a model instance. The model
is not saved after deletion of the file(s) since this is meant
to be used with the pre_delete signal.
'''
for field_name, _ in instance.__dict__.iteritems():
field = getattr(instance, field_name)
if issubclass(field.__class__, FieldFile) and field.name:
field.delete(save=False)
class LogManager(models.Manager):
def create_log(self, work_file, errors):
"""
:param work_file: executing file
:param errors: list of errors ([{'event name':['err1', 'err2']}])
:return: object log
"""
LOG_DIRECTORY = settings.MEDIA_ROOT+'import_xls/logs/'
name= '111.txt'
filename = LOG_DIRECTORY + name
log_file = open(filename, "w")
for error in errors:
event_name = ';'.join(error.keys())
errs = ''
for err in error.values():
errs += '; '.join(err)
errs += ';'
log_file.write('%s: %s\n'%(event_name, errs))
log_file.close()
#update.log_file.name = 'updates/'+name
log = Log(work_file=work_file)
log.log.name = 'import_xls/logs/' + name
#log = Log.objects.create(work_file=work_file, log=log_file)
log.save()
return log
def create_log_name(self, work_file):
log = Log.objects.create(work_file=work_file)
LOG_DIRECTORY = settings.MEDIA_ROOT+'import_xls/logs/'
name= 'log_%d.log'%log.id
filename = LOG_DIRECTORY + name
log_file = open(filename, "w").close()
log.log.name = 'import_xls/logs/' + name
log.save()
return log
class Log(models.Model):
work_file = models.FileField(upload_to=get_doc_dir)
log = models.FileField(upload_to='import_xls/logs/', blank=True)
type = models.CharField(max_length=10, default='IMPORT')
created = models.DateTimeField(auto_now_add=True)
objects = models.Manager()
custom = LogManager()
class Meta:
ordering = ['-created']
pre_delete.connect(file_cleanup, sender=Log)

@ -89,9 +89,13 @@ def to_theme(obj, value):
theme_ids = value.split(',') theme_ids = value.split(',')
if theme_ids == ['']: if theme_ids == ['']:
return return u'Неправильное значение'
obj.theme.clear() obj.theme.clear()
obj.theme.add(*Theme.objects.filter(id__in=theme_ids)) obj.theme.add(*Theme.objects.filter(id__in=theme_ids))
if not Theme.objects.filter(id__in=theme_ids).exists():
return u'Нет совпадений'
return None
def to_tag(obj,value): def to_tag(obj,value):
if value == [""]: if value == [""]:
@ -101,8 +105,7 @@ def to_tag(obj,value):
if names: if names:
obj.tag.clear() obj.tag.clear()
obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all())) obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all()))
else: return None
return
@ -171,7 +174,7 @@ def save_logo(obj, path):
try: try:
alt_name = get_alternative_filename(full_path, file_name) alt_name = get_alternative_filename(full_path, file_name)
except UnicodeEncodeError: except UnicodeEncodeError:
return None return u'Некоректное название файла'
download_to = full_path+alt_name download_to = full_path+alt_name
@ -197,14 +200,14 @@ def save_logo(obj, path):
f.close() f.close()
except: except:
# can be timeout # can be timeout
return None return u'Превышено время ожидания'
obj.logo = logo_path + alt_name obj.logo = logo_path + alt_name
try: try:
obj.save() obj.save()
except: except:
print('logo exception. logo: %s'%obj.logo) print('logo exception. logo: %s'%obj.logo)
return None return u'Неизвестная ошибка'
@ -213,10 +216,10 @@ def check_quality_label(obj, value, label):
try: try:
value = int(value) value = int(value)
except: except:
return bit return None
if value: if value:
setattr(bit, label, True) setattr(bit, label, True)
return bit return None
def to_user(value): def to_user(value):
try: try:

@ -31,6 +31,8 @@ urlpatterns = required(
url(r'^webinar/', include('webinar.admin_urls')), url(r'^webinar/', include('webinar.admin_urls')),
url(r'^settings/', include('settings.admin_urls')), url(r'^settings/', include('settings.admin_urls')),
url(r'^meta/', include('meta.admin_urls')), url(r'^meta/', include('meta.admin_urls')),
url(r'^import_xls/', include('import_xls.admin_urls')),
url(r'^language/add/', 'directories.admin.language_add'), url(r'^language/add/', 'directories.admin.language_add'),
url(r'^currency/add/', 'directories.admin.currency_add'), url(r'^currency/add/', 'directories.admin.currency_add'),
# ajax requests # ajax requests

@ -284,6 +284,7 @@ INSTALLED_APPS = (
'directories', 'directories',
'exposition', 'exposition',
'file', 'file',
'import_xls',
'news', 'news',
'note', 'note',
'organiser', 'organiser',

@ -160,6 +160,10 @@ def random_social(value):
def random3(value): def random3(value):
return random.randrange(0,3) return random.randrange(0,3)
@register.filter
def random4(value):
return random.randrange(0,4)
@register.filter @register.filter
def random5(value): def random5(value):
return random.randrange(0,5) return random.randrange(0,5)

@ -10,6 +10,7 @@ from theme.models import Tag, Theme
from place_exposition.models import PlaceExposition from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference from place_conference.models import PlaceConference
from company.models import Company from company.models import Company
from conference.models import Conference
# every this model must have method get_subcategories # every this model must have method get_subcategories
categories = {'area':{'sub':True, 'model':Area, 'sub_categorie_name':'co'}, categories = {'area':{'sub':True, 'model':Area, 'sub_categorie_name':'co'},
@ -43,17 +44,20 @@ def search_autocomplete(request):
term = request.GET['term'] term = request.GET['term']
form = request.GET['form'] form = request.GET['form']
if form == 'place': if form == 'place':
areas = [{'text':item.name, 'id':item.id, 'name':'area'} for item in Area.objects.filter(translations__name__contains=term)] qs = list(SearchQuerySet().models(Country, City, Area).autocomplete(content_auto=term)[:6])
countries = [{'text':item.name, 'id':item.id, 'name':'co'} for item in Country.objects.select_related('exposition_country')\ objects = [{'text':get_by_lang(item, 'name', lang), 'id': item.pk, 'name': item.form_name} for item in qs]
.filter(exposition_country__country__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()] #areas = [{'text':item.name, 'id':item.id, 'name':'area'} for item in Area.objects.filter(translations__name__contains=term)]
cities = [{'text':item.name, 'id':item.id, 'name':'ci'} for item in City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()] #countries = [{'text':item.name, 'id':item.id, 'name':'co'} for item in Country.objects.select_related('exposition_country')\
# .filter(exposition_country__country__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()]
objects = areas + countries + cities #cities = [{'text':item.name, 'id':item.id, 'name':'ci'} for item in City.objects.select_related('exposition_city')\
return HttpResponse(json.dumps(objects), content_type='application/json') # .filter(exposition_city__city__isnull=False, translations__language_code=lang, translations__name__contains=term).distinct()]
#objects = areas + countries + cities
return HttpResponse(json.dumps(objects, indent=4), content_type='application/json')
if form == 'subj': if form == 'subj':
objects = [{'text': get_by_lang(item, 'name', lang), 'id':item.pk, 'name': item.form_name, 'cat': get_by_lang(item, 'parent', lang)} for item in SearchQuerySet().models(Theme, Tag).autocomplete(content_auto=term)] objects = [{'text': get_by_lang(item, 'name', lang), 'id':item.pk, 'name': item.form_name, 'cat': get_by_lang(item, 'parent', lang)} for item in SearchQuerySet().models(Theme, Tag).autocomplete(content_auto=term)]
return HttpResponse(json.dumps(objects), content_type='application/json') return HttpResponse(json.dumps(objects, indent=4), content_type='application/json')
else: else:
return HttpResponse("Don't implemented yet") return HttpResponse("Don't implemented yet")
@ -91,17 +95,20 @@ def expo_autosearch(request):
if request.GET: if request.GET:
lang = translation.get_language() lang = translation.get_language()
term = request.GET['term'] term = request.GET['term']
term = term.strip()
d = datetime.date.today() d = datetime.date.today()
expos = list(SearchQuerySet().models(Exposition).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6]) expos = list(SearchQuerySet().models(Exposition).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6])
themes = list(SearchQuerySet().models(Tag).autocomplete(content_auto=term).order_by('text')[:15]) confs = list(SearchQuerySet().models(Conference).filter(data_end__gte=d).autocomplete(content_auto=term).order_by('data_begin','text')[:6])
res = expos + themes tags = list(SearchQuerySet().models(Tag).autocomplete(content_auto=term).order_by('text')[:6])
themes = list(SearchQuerySet().models(Theme).autocomplete(content_auto=term).order_by('text')[:6])
res = expos + themes + tags + confs
result = [{'cat': get_by_lang(item, 'catalog_name', lang), result = [{'cat': get_by_lang(item, 'catalog_name', lang),
'text': '%s (%s)'%(get_by_lang(item, 'name', lang),get_by_lang(item, 'parent', lang)) if get_by_lang(item, 'parent', lang) else get_by_lang(item, 'name', lang), 'text': '%s (%s)'%(get_by_lang(item, 'name', lang),get_by_lang(item, 'parent', lang)) if get_by_lang(item, 'parent', lang) else get_by_lang(item, 'name', lang),
'url':item.url, 'url':item.url,
'id':item.pk, 'id':item.pk,
'name': item.form_name} for item in res] 'name': item.form_name} for item in res]
result = sorted(result, key=lambda x:x['cat'], reverse=True) result = sorted(result, key=lambda x:x['cat'], reverse=True)
return HttpResponse(json.dumps(result), content_type='application/json') return HttpResponse(json.dumps(result, indent=4), content_type='application/json')
else: else:
raise Http404 raise Http404

@ -112,13 +112,13 @@ function postStat(data, textStatus){
$(document).ready(function(){ $(document).ready(function(){
/*
$('#id_created').datetimepicker({ $('#id_created').datetimepicker({
todayHighlight: true, todayHighlight: true,
format : 'yyyy-mm-dd', format : 'yyyy-mm-dd',
minView:2 minView:2
}); });
*/
$('#photo_form').on('submit', function(e){ $('#photo_form').on('submit', function(e){
e.preventDefault(); e.preventDefault();
var url = $(this).attr('action'); var url = $(this).attr('action');

@ -31,6 +31,10 @@
<link href="{% static 'css/uploadify.css' %}" rel='stylesheet'> <link href="{% static 'css/uploadify.css' %}" rel='stylesheet'>
{# The fav icon #} {# The fav icon #}
<link rel="shortcut icon" href="img/favicon.ico"> <link rel="shortcut icon" href="img/favicon.ico">
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script src="{% static 'custom_js/main.js' %}"></script>
{% block scripts %} {% block scripts %}
{% endblock %} {% endblock %}
@ -72,10 +76,7 @@
</div> </div>
</body> </body>
{# datetimepicker #}
<link href="{% static 'js/datetimepicker/css/datetimepicker.css' %}" rel="stylesheet"/>
<script src="{% static 'js/datetimepicker/js/bootstrap-datetimepicker.js' %}"></script>
<script src="{% static 'custom_js/main.js' %}"></script>
{% block bot_scripts %} {% block bot_scripts %}
{% endblock %} {% endblock %}
</html> </html>

@ -181,6 +181,14 @@
<span class="help-inline">{{ form.web_page.errors }}</span> <span class="help-inline">{{ form.web_page.errors }}</span>
</div> </div>
</div> </div>
{# organiser #}
<div class="control-group {% if form.org.errors %}error{% endif %}">
<label class="control-label">{{ form.org.label }}:</label>
<div class="controls">{{ form.org }}
<span class="help-inline">{{ form.org.errors }}</span>
</div>
</div>
{# link #} {# link #}
<div class="control-group {% if form.link.errors %}error{% endif %}"> <div class="control-group {% if form.link.errors %}error{% endif %}">
<label class="control-label">{{ form.link.label }}:</label> <label class="control-label">{{ form.link.label }}:</label>

@ -30,15 +30,8 @@
<script src="{% static 'custom_js/formset_add.js' %}"></script> <script src="{% static 'custom_js/formset_add.js' %}"></script>
<!--
{# ajax #}
<script src="{% static 'custom_js/timetable_post.js' %}"></script>
<script src="{% static 'custom_js/place_city_ajax.js' %}"></script>
<script src="{% static 'custom_js/select_tag.js' %}"></script>
-->
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function(){ $(document).ready(function(){
$('#id_data_begin').datetimepicker({ $('#id_data_begin').datetimepicker({
@ -223,6 +216,13 @@
<span class="help-inline">{{ form.web_page.errors }}</span> <span class="help-inline">{{ form.web_page.errors }}</span>
</div> </div>
</div> </div>
{# organiser #}
<div class="control-group {% if form.org.errors %}error{% endif %}">
<label class="control-label">{{ form.org.label }}:</label>
<div class="controls">{{ form.org }}
<span class="help-inline">{{ form.org.errors }}</span>
</div>
</div>
{# products #} {# products #}
{% with field='products' form=form languages=languages %} {% with field='products' form=form languages=languages %}
{% include 'admin/forms/multilang.html' %} {% include 'admin/forms/multilang.html' %}
@ -371,32 +371,6 @@
</div> </div>
</div> </div>
<div class="box span8">
<div class="box-header well">
<h2><i class="icon-pencil"></i>Участники</h2>
</div>
<div class="box-content">
{# organiser #}
<div class="control-group {% if form.organiser.errors %}error{% endif %}">
<label class="control-label">{{ form.organiser.label }}:</label>
<div class="controls">{{ form.organiser }}
<span class="help-inline">{{ form.organiser.errors }}</span>
</div>
</div>
{# company #}
<div class="control-group {% if form.company.errors %}error{% endif %}">
<label class="control-label">{{ form.company.label }}:</label>
<div class="controls">{{ form.company }}
<span class="help-inline">{{ form.company.errors }}</span>
</div>
</div>
</div>
</div>
<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>Деловая программа</h2>

@ -0,0 +1,47 @@
{% extends 'base.html' %}
{% load static %}
{% block body %}
{% comment %}
Displays lists of all cities in the table
and creating buttons which can change each city
{% endcomment %}
<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>Время импорта</th>
<th>Робочий файл</th>
<th>Лог</th>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
{% for item in object_list %}
<tr>
<td>{{ item.created|date:"Y-m-d H:m:s" }}</td>
<td><a href="/admin/log/work_file/{{ item.id }}/">скачать</a></td>
<td><a href="/admin/log/log/{{ item.id }}/">скачать</a></td>
<td class="center sorting_1">
<a class="btn btn-danger delete" href="/admin/import/log/delete/{{ item.id }}/">
<i class="icon-trash icon-white"></i> Удалить
</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="btn btn-success" href="/admin/city/add"><i class="icon-plus-sign icon-white"></i> Добавить город</a>
</div>
{% include 'admin/includes/admin_pagination.html' with page_obj=objects %}
</div>
{% endblock %}

@ -0,0 +1,15 @@
{% extends 'base.html' %}
{% block body %}
<form action="" method="post"> {% csrf_token %}
<div class="alert alert-danger">
<p>Вы действительно хотите удалить <b>{{ object }}</b>?</p>
</div>
<input type="submit" class="btn-primary" value="Да">
<a class="btn" href="/admin/import/log/">Нет</a>
</form>
{% endblock %}

@ -92,7 +92,6 @@
); );
var rdr = $('#expo-ad-popup').attr('data-rdr'); var rdr = $('#expo-ad-popup').attr('data-rdr');
sendData = {'rdr': rdr}; sendData = {'rdr': rdr};
console.log(rdr);
$.ajax({ $.ajax({
url: '/ajax/get_popover/', url: '/ajax/get_popover/',
data: sendData, data: sendData,

@ -154,10 +154,15 @@
</dd> </dd>
{% else %} {% else %}
{% if event.org %} {% if event.org %}
<dt>{% trans 'Организатор' %}:</dt>
<dd> {% for item in event.org_split %}
{{ event.org }} <dt>{% if forloop.counter == 1 %}{% trans 'Организатор' %}:{% endif %}</dt>
</dd>
<dd>
{{ item }}
</dd>
{% endfor %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if event.place_alt %} {% if event.place_alt %}

@ -19,7 +19,7 @@
<span class="visitors" title="Посетители">{{ exposition.visitors }}</span> <span class="visitors" title="Посетители">{{ exposition.visitors }}</span>
{% endif %} {% endif %}
{% if exposition.members %} {% if exposition.members %}
<span class="participants" title="Участники">{{ exposition.members }}</span> <span classlinkebreaksbr="participants" title="Участники">{{ exposition.members }}</span>
{% endif %} {% endif %}
</div> </div>
<div class="i-discount"> <div class="i-discount">
@ -159,10 +159,14 @@
</dd> </dd>
{% else %} {% else %}
{% if exposition.org %} {% if exposition.org %}
<dt>{% trans 'Организатор' %}:</dt> {% for item in exposition.org_split %}
<dd> <dt>{% if forloop.counter == 1 %}{% trans 'Организатор' %}:{% endif %}</dt>
{{ exposition.org }}
</dd> <dd>
{{ item }}
</dd>
{% endfor %}
{% endif %} {% endif %}
{% endif %} {% endif %}
{% if exposition.place_alt %} {% if exposition.place_alt %}

@ -8,11 +8,7 @@
<li> <li>
<a href="{{ exposition.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a> <a href="{{ exposition.get_permanent_url }}service/translator/">{% trans 'Устный переводчик' %}</a>
</li> </li>
{% if exposition.country_id not in sng_countries %}
<li>
<a href="{{ exposition.get_permanent_url }}service/visit/">{% trans 'Бизнес-тур "под ключ"' %}</a>
</li>
{% endif %}
<li> <li>
<a href="{{ exposition.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a> <a href="{{ exposition.get_permanent_url }}service/remote/">{% trans 'Заочное посещение' %}</a>
</li> </li>

@ -7,7 +7,6 @@
{% comment %}<li><a href="/service/tickets/">{% trans 'Билеты на выставки' %}</a></li>{% endcomment %} {% comment %}<li><a href="/service/tickets/">{% trans 'Билеты на выставки' %}</a></li>{% endcomment %}
<li><a href="/service/remote/">{% trans 'Заочное посещение' %}</a></li> <li><a href="/service/remote/">{% trans 'Заочное посещение' %}</a></li>
<li><a href="/service/participation/">{% trans 'Участие в выставках' %}</a></li> <li><a href="/service/participation/">{% trans 'Участие в выставках' %}</a></li>
<li><a href="/service/visit/">{% trans 'Посещение выставки' %}</a></li>
</ul> </ul>
</nav> </nav>
</div> </div>

@ -1 +1 @@
{{ object.name }} {{ object.get_index_text }}

@ -133,7 +133,7 @@ class Theme(TranslatableModel):
parent = {} parent = {}
return parent return parent
from django.db import IntegrityError
class Tag(TranslatableModel): class Tag(TranslatableModel):
""" """
Create Tag model Create Tag model
@ -167,6 +167,15 @@ class Tag(TranslatableModel):
#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)
def save(self, *args, **kwargs):
try:
super(Tag, self).save(*args, **kwargs)
except IntegrityError:
theme = self.theme
self.url = '%s_%s'%(theme.url, self.url)
super(Tag, self).save(*args, **kwargs)
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))

@ -170,4 +170,4 @@ class TagIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin):
def index_queryset(self, using=None): def index_queryset(self, using=None):
#return self.get_model().active.all() #return self.get_model().active.all()
return self.get_model().objects.filter() return self.get_model().active.all()
Loading…
Cancel
Save