diff --git a/exposition/management/commands/exposition_en.py b/exposition/management/commands/exposition_en.py index a0ae9d69..67addd68 100644 --- a/exposition/management/commands/exposition_en.py +++ b/exposition/management/commands/exposition_en.py @@ -4,7 +4,7 @@ from city.models import City from country.models import Country from place_exposition.models import PlaceExposition import xlrd, xlwt -from import_xls.excel_settings import import_settings, place_exp_sett +from import_xls.excel_settings import place_exp_sett from django.conf import settings diff --git a/functions/admin_views.py b/functions/admin_views.py index d20b361d..8a8ce342 100644 --- a/functions/admin_views.py +++ b/functions/admin_views.py @@ -128,9 +128,9 @@ class AdminListView(FormView): def get_context_data(self, **kwargs): context = super(AdminListView, self).get_context_data(**kwargs) if issubclass(self.model, TranslatableModel): - qs = self.model.objects.language('all').all().order_by('name') + qs = self.model.objects.language().all().order_by('name') else: - qs = self.model.objects.all().order_by('name') + qs = self.model.objects.all().order_by('-modified') result = paginate_results(qs, page=self.request.GET.get('page')) context['object_list'] = result return context diff --git a/import_xls/admin.py b/import_xls/admin.py index 0ceee351..c0820c30 100644 --- a/import_xls/admin.py +++ b/import_xls/admin.py @@ -1,22 +1,17 @@ # -*- coding: utf-8 -*- -from django.core.context_processors import csrf from django.shortcuts import render_to_response from django.http import HttpResponseRedirect, HttpResponse -from django.contrib.auth.decorators import login_required -from django.db.models.loading import get_model -# -import xlwt -import xlrd -# -from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, ImportOrganiserForm,\ - ImportPlaceConferenceForm, ImportPlaceExpositionForm -from export_forms import ExportEventForm, ExportOrganiserForm, ExportThemeForm, ExportTagForm,\ - ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\ - ExportCityForm from django.views.generic import FormView, ListView, DeleteView from django.conf import settings from django.contrib import messages from django.shortcuts import get_object_or_404 +from import_xls.models import Log +from import_forms import ImportEventForm, ImportThemeForm, ImportTagForm, \ + ImportPlaceConferenceForm, ImportPlaceExpositionForm +from export_forms import ExportEventForm, ExportThemeForm, ExportTagForm,\ + ExportUserForm, ExportCompanyForm, ExportPlaceConferenceForm, ExportPlaceExpositionForm, ExportBlogForm,\ + ExportCityForm + def xls_to_response(xls, fname): response = HttpResponse(mimetype="application/ms-excel") @@ -41,7 +36,6 @@ class ImportView(FormView): return render_to_response(self.template_name, context) - class ExportView(FormView): """ abstract class @@ -57,85 +51,93 @@ class ExportView(FormView): return HttpResponseRedirect(self.success_url) return xls_to_response(workbook, f_name) -class ExportOrganiser(ExportView): - form_class = ExportOrganiserForm - success_url = '/admin/export-organiser' class ExportTheme(ExportView): form_class = ExportThemeForm success_url = '/admin/export-theme' + class ExportTag(ExportView): form_class = ExportTagForm success_url = '/admin/export-tag' + class ExportUser(ExportView): form_class = ExportUserForm success_url = '/admin/export-user' + class ExportCompany(ExportView): form_class = ExportCompanyForm success_url = '/admin/export-company' + class ExportPlaceConference(ExportView): form_class = ExportPlaceConferenceForm success_url = '/admin/export-place_conference' + class ExportPlaceExposition(ExportView): form_class = ExportPlaceExpositionForm success_url = '/admin/export-place_exposition' + class ExportBlog(ExportView): form_class = ExportBlogForm success_url = '/admin/export-blog/' + class ExportBlog(ExportView): form_class = ExportBlogForm success_url = '/admin/export-blog/' + class ExportCity(ExportView): form_class = ExportCityForm success_url = '/admin/export-city/' - -from import_xls.models import Log class ImportEvent(FormView): form_class = ImportEventForm success_url = '/admin/import-event/' template_name = 'admin/import templates/import_event.html' + def form_valid(self, form): errors = form.save_file_debug() return HttpResponseRedirect('/admin/import/log/') - #messages.success(self.request, 'Success') - #context = self.get_context_data() - #context['import_errors'] = errors - #context['form'] = form - #return render_to_response(self.template_name, context) +class ImportPlaceExposition(FormView): + form_class = ImportPlaceExpositionForm + success_url = '/admin/import-place_exposition/' + template_name = 'admin/import templates/import.html' + + def form_valid(self, form): + errors = form.save_file_debug() + return HttpResponseRedirect(self.success_url) + +class ImportPlaceConference(ImportView): + form_class = ImportPlaceConferenceForm + success_url = '/admin/import-place_conference' + + def form_valid(self, form): + errors = form.save_file_debug() + return HttpResponseRedirect(self.success_url) class ImportTheme(ImportView): form_class = ImportThemeForm success_url = '/admin/import-theme' + class ImportTag(ImportView): form_class = ImportTagForm success_url = '/admin/import-tag' -class ImportOrganiser(ImportView): - form_class = ImportOrganiserForm - success_url = '/admin/import-organiser' -class ImportPlaceExposition(ImportView): - form_class = ImportPlaceExpositionForm - success_url = '/admin/import-place_exposition' -class ImportPlaceConference(ImportView): - form_class = ImportPlaceConferenceForm - success_url = '/admin/import-place_conference' + class ExportEvent(ExportView): form_class = ExportEventForm @@ -148,6 +150,7 @@ class LogList(ListView): paginate_by = settings.ADMIN_PAGINATION template_name = 'admin/import templates/log.html' + class LogDelete(DeleteView): model = Log success_url = '/admin/import/log/' @@ -163,11 +166,12 @@ def log_file(request, log_id): 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) + 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 \ No newline at end of file diff --git a/import_xls/admin_urls.py b/import_xls/admin_urls.py index 0d7af157..1aae00e4 100644 --- a/import_xls/admin_urls.py +++ b/import_xls/admin_urls.py @@ -1,25 +1,21 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, url - -from admin import ImportTheme, ImportEvent, ImportOrganiser, ImportTag, ImportPlaceExposition, ImportPlaceConference - -from admin import ExportTheme, ExportEvent, ExportOrganiser, ExportTag, ExportPlaceExposition,\ - ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList from import_xls.admin import LogDelete +from admin import ImportTheme, ImportEvent, ImportTag, ImportPlaceExposition, ImportPlaceConference +from admin import ExportTheme, ExportEvent, ExportTag, ExportPlaceExposition,\ + ExportPlaceConference, ExportCompany, ExportUser, ExportBlog, ExportCity, LogList urlpatterns = patterns('', url(r'^import-event/$', ImportEvent.as_view()), url(r'^import-theme/$', ImportTheme.as_view()), url(r'^import-tag/$', ImportTag.as_view()), - url(r'^import-organiser/$', ImportOrganiser.as_view()), url(r'^import-place_exposition/$', ImportPlaceExposition.as_view()), url(r'^import-place_conference/$', ImportPlaceConference.as_view()), # url(r'^export-event/$', ExportEvent.as_view()), url(r'^export-theme/$', ExportTheme.as_view()), url(r'^export-tag/$', ExportTag.as_view()), - url(r'^export-organiser/$', ExportOrganiser.as_view()), url(r'^export-place_exposition/$', ExportPlaceExposition.as_view()), url(r'^export-place_conference/$', ExportPlaceConference.as_view()), url(r'^export-user/$', ExportUser.as_view()), diff --git a/import_xls/excel_settings.py b/import_xls/excel_settings.py index 936c5913..2754dd45 100644 --- a/import_xls/excel_settings.py +++ b/import_xls/excel_settings.py @@ -1,12 +1,22 @@ # -*- coding: utf-8 -*- +import urllib2 +from django.conf import settings +from django.contrib.contenttypes.models import ContentType +from django.core.validators import validate_email, URLValidator +from file.models import FileModel +from functions.files import get_alternative_filename +from place_exposition.models import EXPOSITION_TYPE +from place_exposition.models import Hall # bad practice of importing, but to many functions must be imported from .utils import * + def get_bool(value): if value: return 1 return '' + def get_int(value): if not value: return '' @@ -30,12 +40,14 @@ def get_tag(value): tag_names = [item['name'] for item in value.language('ru').all().values('name')] return ','.join(tag_names) + def get_place_type(value): for t in EXPOSITION_TYPE: if value == t[0]: return t[1] return t[0][1] + def get_periodic(value): if value: value = float(value) @@ -45,6 +57,7 @@ def get_periodic(value): return periodic.get(value, '') return '' + def get_quality(value, field): flags = {u'UFI': 'ufi', u'РСВЯ': 'rsva', u'EXPORATING': 'exporating'} v = flags.get(field) @@ -56,45 +69,6 @@ def get_quality(value, field): return '' - -place_settings=[ - {'name': 'id', 'verbose_name': u'id', 'type': get_int, 'width':1500}, - {'name': 'url', 'verbose_name': u'URL', 'type': unicode}, - {'name': 'name', 'verbose_name': u'Название', 'type': unicode}, - {'name': 'type', 'verbose_name': u'Тип', 'type': get_place_type},########## - {'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode}, - {'name': 'country', 'verbose_name': u'Страна', 'type': unicode}, - {'name': 'city', 'verbose_name': u'Город', 'type': unicode}, - {'name': 'address', 'verbose_name': u'Адресс', 'type': unicode}, - {'name': 'phone', 'verbose_name': u'Тел.', 'type': get_int}, - {'name': 'fax', 'verbose_name': u'Факс', 'type': get_int}, - {'name': 'web_page', 'verbose_name': u'Веб-сайт', 'type': unicode}, - {'name': 'email', 'verbose_name': u'Email', 'type': unicode}, - {'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode}, - {'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode}, - {'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int}, - {'name': 'event_in_year', 'verbose_name': u'Количество мероприятий в год', 'type': get_int}, - {'name': 'total_area', 'verbose_name': u'Общая выставочная площадь, кв. м.', 'type': get_int}, - {'name': 'closed_area', 'verbose_name': u'Закрытая выставочная площадь, кв. м.', 'type': get_int}, - {'name': 'open_area', 'verbose_name': u'Открытая выставочная площадь, кв. м.', 'type': get_int}, - {'name': 'total_pavilions', 'verbose_name': u'Количество павильонов', 'type': get_int}, - {'name': 'total_halls', 'verbose_name': u'Конференц-залы', 'type': get_int}, - {'name': 'bank', 'verbose_name': u'Банк/Банкоматы/Обмен валюты', 'type': get_bool}, - {'name': 'children_room', 'verbose_name': u'Детская комната', 'type': get_bool}, - {'name': 'disabled_service', 'verbose_name': u'Сервис для людей с ограниченными физическими возможностями', 'type': get_bool}, - {'name': 'conference_centre', 'verbose_name': u'Конгресс-центр', 'type': get_bool}, - {'name': 'business_centre', 'verbose_name': u'Бизнес-центр', 'type': get_bool}, - {'name': 'online_registration', 'verbose_name': u'On-line регистрация', 'type': get_bool}, - {'name': 'wifi', 'verbose_name': u'Wi-Fi', 'type': get_bool}, - {'name': 'cafe', 'verbose_name': u'Кафе и рестораны', 'type': get_bool}, - {'name': 'terminals', 'verbose_name': u'Информационные терминалы', 'type': get_bool}, - {'name': 'parking', 'verbose_name': u'Парковка', 'type': get_bool}, - {'name': 'press_centre', 'verbose_name': u'Пресс-центр', 'type': get_bool}, - {'name': 'mobile_application', 'verbose_name': u'Мобильное приложение', 'type': get_bool}, - -] - - def to_theme_type(st): if not st: return 15 @@ -105,37 +79,15 @@ def to_theme_type(st): return flag - - - -def to_currency(value): - if value=='USD': - return value - if value=='EUR': - return value - print(value) - return 'USD' - -def to_logo(url): - return None - -def to_photo(url): - return None - -def to_map(url): - return None - -from django.core.validators import validate_email, URLValidator - def to_url(url): validate = URLValidator() - try: validate(url) except: return '' return url + def to_email(email): try: validate_email(email) @@ -143,12 +95,6 @@ def to_email(email): return '' return email -from file.models import FileModel -import urllib2 -from django.conf import settings -from django.contrib.contenttypes.models import ContentType -from functions.files import get_alternative_filename - def save_file(obj, value, purpose): if not obj.id: @@ -178,42 +124,13 @@ def save_file(obj, value, purpose): file.save() -from file.models import Photo -def save_photo(obj, value): - if not obj.id: - return None - - urls = value.split(';') - - for url in urls: - - file_name = url.split('/')[-1] - alt_name = get_alternative_filename(settings.MEDIA_ROOT+'imgs/', file_name) - download_to = settings.MEDIA_ROOT+'photos/'+alt_name - try: - response = urllib2.urlopen(url, timeout=3) - except: - continue - - with open(download_to,'wb') as f: - f.write(response.read()) - f.close() - - - file_name ='photos/'+alt_name - content_type = ContentType.objects.get_for_model(obj) - photo = Photo(file_path=file_name, file_type='JPG', - content_type=content_type, object_id=obj.id) - photo.save() - - -from place_exposition.models import EXPOSITION_TYPE def to_type(value): for t in EXPOSITION_TYPE: if value == t[1]: return t[0] return 'Exposition complex' + def to_phone(value): if value: if isinstance(value, float) or isinstance(value, int): @@ -227,9 +144,6 @@ def to_phone(value): return value - - -from place_exposition.models import Hall def save_halls(obj, value): halls = value.split(';') res = [] @@ -266,51 +180,11 @@ def save_halls(obj, value): print('---------------------------------') - - - -place_exp_sett = { - u'ID':{u'field': u'id', u'func': to_int}, - u'Название ВЦ':{u'field': u'name', u'func': unicode}, - u'Тип':{u'field': u'type', u'func': to_type}, - u'Краткое описание':{u'field': u'main_title', u'func': unicode}, - u'Страна':{u'field': u'country', u'func': to_country}, - u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'}, - u'Описание':{u'field': u'description', u'func': unicode}, - u'Адрес':{u'field': u'adress', u'func': unicode}, - u'Тел.':{u'field': u'phone', u'func': to_phone}, - u'Факс':{u'field': u'fax', u'func': to_phone}, - u'Фото':{u'field': u'photo', u'func': save_photo, u'method': True}, - u'Лого':{u'field': u'logo', u'func': save_logo, u'method': True}, - u'Веб-сайт':{u'field': u'web_page', u'func': unicode}, - u'Email':{u'field': u'email', u'func': unicode}, - u'Карта проезда':{u'field': u'map', u'func': save_file, u'method': True, u'purpose': 'map'}, - u'Виртуальный тур':{u'field': u'virtual_tour', u'func': to_url}, - u'Год основания':{u'field': u'foundation_year', u'func': to_int}, - u'Валюта':{u'field': u'currency', u'func': to_currency}, - u'Количество мероприятий в год':{u'field': u'event_in_year', u'func': to_int}, - u'Общая выставочная площадь, кв. м.':{u'field': u'total_area', u'func': to_int}, - u'Закрытая выставочная площадь, кв. м.':{u'field': u'closed_area', u'func': to_int}, - u'Открытая выставочная площадь, кв. м.':{u'field': u'open_area', u'func': to_int}, - u'Количество павильонов':{u'field': u'total_pavilions', u'func': to_int}, - u'Площадь павильона':{u'field': u'halls', u'func': save_halls, u'method': True}, - u'Конференц-залы':{u'field': u'total_halls', u'func': to_int}, - u'Схема территории':{u'field': u'scheme', u'func': save_file, u'method': True, u'purpose': 'scheme teritory'},#сделать - u'Банк/Банкоматы/Обмен валюты':{u'field': u'bank', u'func': bool}, - u'Детская комната':{u'field': u'children_room', u'func': bool}, - u'Сервис для людей с ограниченными физическими возможностями':{u'field': u'disabled_service', u'func': bool}, - u'Конгресс-центр':{u'field': u'conference_centre', u'func': bool}, - u'Бизнес-центр':{u'field': u'business_centre', u'func': bool}, - u'On-line регистрация':{u'field': u'online_registration', u'func': bool}, - u'Wi-Fi':{u'field': u'wifi', u'func': bool}, - u'Кафе и рестораны':{u'field': u'cafe', u'func': bool}, - u'Информационные терминалы':{u'field': u'terminals', u'func': bool}, - u'Парковка':{u'field': u'parking', u'func': bool}, - u'Пресс-центр':{u'field': u'press_centre', u'func': bool}, - u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool}, -} - - +def get_date(value): + try: + return value.strftime('%d.%m.%Y') + except AttributeError: + return '' article_sett = { @@ -321,66 +195,7 @@ article_sett = { u'Создана':{u'field': u'created', u'func': to_datetime} } -def get_date(value): - try: - return value.strftime('%d.%m.%Y') - except AttributeError: - return '' - - -event_export_sett = [ - {'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500}, - {'name': 'url', 'verbose_name': u'Url', 'type': unicode}, - {'name': 'name', 'verbose_name': u'Название', 'type': unicode}, - {'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode}, - {'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date}, - {'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date}, - {'name': 'country', 'verbose_name': u'Страна', 'type': unicode}, - {'name': 'city', 'verbose_name': u'Город', 'type': unicode}, - {'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place}, - {'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000}, - {'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000}, - {'name': 'description', 'verbose_name': u'Описание события', 'type': unicode}, - {'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int}, - {'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic}, - {'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience}, - {'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode}, - {'name': 'products', 'verbose_name': u'Экспонируемые продукты', 'type': unicode}, - {'name': 'time', 'verbose_name': u'Время работы', 'type': unicode}, - {'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode}, - {'name': 'currency', 'verbose_name': u'Валюта', 'type': unicode}, - {'name': 'price_day', 'verbose_name': u'Стоимость билета 1 день', 'type': unicode}, - {'name': 'price_all', 'verbose_name': u'Стоимость билета все дни', 'type': unicode}, - {'name': 'pre_condition', 'verbose_name': u'Условия предварительной регистрации', 'type': unicode}, - {'name': 'price_day_bar', 'verbose_name': u'Стоимость на стойке 1 день', 'type': unicode}, - {'name': 'price_all_bar', 'verbose_name': u'Стоимость на стойке все дни', 'type': unicode}, - {'name': 'stand_condition', 'verbose_name': u'Условия регистрации на стойке', 'type': unicode}, - {'name': 'visit_note', 'verbose_name': u'Примечание по посещению', 'type': unicode}, - {'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int}, - {'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000}, - {'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int}, - {'name': 'visitors', 'verbose_name': u'Посетители', 'type': get_int}, - {'name': 'members', 'verbose_name': u'Участники', 'type': get_int}, - #{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, !!! delete from import - {'name': 'area', 'verbose_name': u'Площадь', 'type': get_int}, - {'name': 'min_closed_area', 'verbose_name': u'Min_Raw кв.м.', 'type': get_int}, - {'name': 'max_closed_area', 'verbose_name': u'Max_Raw кв.м.', 'type': get_int}, - {'name': 'min_closed_equipped_area', 'verbose_name': u'Min_Pack кв.м.', 'type': get_int}, - {'name': 'max_closed_equipped_area', 'verbose_name': u'Max_Pack кв.м.', 'type': get_int}, - {'name': 'max_open_area', 'verbose_name': u'Открытая площадь', 'type': get_int}, - {'name': 'min_stand_size', 'verbose_name': u'Мин. Площадь кв.м.', 'type': get_int}, - {'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int}, - {'name': 'participation_note', 'verbose_name': u'Примечание по участии', 'type': unicode}, - {'name': 'application_deadline', 'verbose_name': u'Крайний срок подачи заявки', 'type': get_date}, - {'name': 'quality_label', 'verbose_name': u'UFI', 'type': get_quality}, #???? - {'name': 'quality_label', 'verbose_name': u'РСВЯ', 'type': get_quality},#??? - {'name': 'quality_label', 'verbose_name': u'EXPORATING', 'type': get_quality}, #??? - {'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool}, - {'name': 'expohit', 'verbose_name': u'ExpoHIT', 'type': get_bool}, - {'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool}, - -] - +# default export settings field_settings = [ {'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500}, {'name': 'url', 'verbose_name': u'Url', 'type': unicode}, @@ -412,8 +227,6 @@ field_settings = [ {'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int}, {'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000}, {'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int}, - - {'name': 'visit_note', 'verbose_name': u'Посетители', 'type': unicode}, {'name': 'visit_note', 'verbose_name': u'Участники', 'type': unicode}, {'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, @@ -424,7 +237,6 @@ field_settings = [ {'name': 'visit_note', 'verbose_name': u'Max_Pack кв.м.', 'type': unicode}, {'name': 'visit_note', 'verbose_name': u'Открытая площадь', 'type': unicode}, {'name': 'visit_note', 'verbose_name': u'Мин. Площадь кв.м.', 'type': unicode}, - {'name': 'visit_note', 'verbose_name': u'Примечание по участии', 'type': unicode}, {'name': 'visit_note', 'verbose_name': u'Крайний срок подачи заявки', 'type': unicode}, {'name': 'visit_note', 'verbose_name': u'UFI', 'type': unicode}, @@ -432,21 +244,13 @@ field_settings = [ {'name': 'visit_note', 'verbose_name': u'EXPORATING', 'type': unicode}, {'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool}, {'name': 'visit_note', 'verbose_name': u'ExpoHIT', 'type': unicode}, - {'name': 'address', 'verbose_name': u'Адрес', 'type': unicode}, - - {'name': 'email', 'verbose_name': u'Email', 'type': unicode}, {'name': 'phone', 'verbose_name': u'Телефон', 'type': get_int}, - - {'name': 'foundation', 'verbose_name': u'Год основания', 'type': get_int}, #{'name': 'events_number', 'verbose_name': u'Год основания', 'type': get_int}, {'name': 'staff_number', 'verbose_name': u'Год основания', 'type': get_int}, {'name': 'specialization', 'verbose_name': u'Год основания', 'type': unicode}, - - - {'name': 'max_price', 'verbose_name': u'Максимальная цена', 'type': get_int}, {'name': 'min_price', 'verbose_name': u'Минимальная цена', 'type': get_int}, {'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int}, @@ -459,68 +263,221 @@ field_settings = [ {'name': 'min_area', 'verbose_name': u'Минимальная площадь', 'type': get_int}, {'name': 'max_area', 'verbose_name': u'Максимальная площадь', 'type': get_int}, {'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool}, - ] - +# ----------------------EVENT SETTINGS ------------------------- event_sett = { - u'ID':{u'field': u'id', u'func': to_int}, - u'Url':{u'field': u'url', u'func': unicode}, - u'Название':{u'field': u'name', u'func': unicode}, - u'Краткое описание':{u'field': u'main_title', u'func': unicode}, - u'Дата начала:(YYYY-MM-DD)':{u'field': u'data_begin', u'func': to_date}, - u'Дата окончания:(YYYY-MM-DD)':{u'field': u'data_end', u'func': to_date}, - u'Страна':{u'field': u'country', u'func': to_country}, - u'Город':{u'field': u'city_id', u'func': to_city, 'extra_values': 'country'}, - u'Место проведения':{u'field': u'place', u'func': to_place}, - u'ID Тематики':{u'field': u'theme', u'func': to_theme, u'method': True},### - u'Теги':{u'field': u'tag', u'func': to_tag, u'method': True}, - u'Организатор №1':{u'field': u'org', u'func': unicode},#### + u'ID': {u'field': u'id', u'func': to_int}, + u'Url': {u'field': u'url', u'func': unicode}, + u'Название': {u'field': u'name', u'func': unicode}, + u'Краткое описание': {u'field': u'main_title', u'func': unicode}, + u'Дата начала:(YYYY-MM-DD)': {u'field': u'data_begin', u'func': to_date}, + u'Дата окончания:(YYYY-MM-DD)': {u'field': u'data_end', u'func': to_date}, + u'Страна': {u'field': u'country', u'func': to_country}, + u'Город': {u'field': u'city_id', u'func': to_city, 'extra_values': 'country'}, + u'Место проведения': {u'field': u'place', u'func': to_place}, + u'ID Тематики': {u'field': u'theme', u'func': to_theme, u'method': True},### + u'Теги': {u'field': u'tag', u'func': to_tag, u'method': True}, + u'Организатор №1': {u'field': u'org', u'func': unicode},#### #u'Организатор №2':{u'field': u'organiser', u'func': to_tag},#### - u'Описание события':{u'field': u'description', u'func': unicode}, - u'Основные темы':{u'field': u'main_themes', u'func': unicode}, - u'Условия и скидка':{u'field': u'discount_description', u'func': unicode}, - u'Периодичность':{u'field': u'periodic', u'func': to_periodic},### - u'Аудитория':{u'field': u'audience', u'func': to_audience}, - u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url}, - u'Линк на регистрацию':{u'field': u'link', u'func': to_url}, - u'Экспонируемые продукты':{u'field': u'products', u'func': unicode}, - u'Время работы':{u'field': u'time', u'func': unicode}, + u'Описание события': {u'field': u'description', u'func': unicode}, + u'Основные темы': {u'field': u'main_themes', u'func': unicode}, + u'Условия и скидка': {u'field': u'discount_description', u'func': unicode}, + u'Периодичность': {u'field': u'periodic', u'func': to_periodic},### + u'Аудитория': {u'field': u'audience', u'func': to_audience}, + u'Официальный веб-сайт': {u'field': u'web_page', u'func': to_url}, + u'Линк на регистрацию': {u'field': u'link', u'func': to_url}, + u'Экспонируемые продукты': {u'field': u'products', u'func': unicode}, + u'Время работы': {u'field': u'time', u'func': unicode}, u'Логотип':{u'field': u'logo', u'func': save_logo, u'method': True}, - u'Валюта':{u'field': u'currency', u'func': unicode}, - u'Стоимость билета 1 день':{u'field': u'price_day', u'func': unicode}, - u'Стоимость билета все дни':{u'field': u'price_all', u'func': unicode}, - u'Условия предварительной регистрации':{u'field': u'pre_condition', u'func': unicode}, - u'Стоимость на стойке 1 день':{u'field': u'price_day_bar', u'func': unicode}, - u'Стоимость на стойке все дни':{u'field': u'price_all_bar', u'func': unicode}, - u'Условия регистрации на стойке':{u'field': u'stand_condition', u'func': unicode}, - u'Примечание по посещению':{u'field': u'visit_note', u'func': unicode}, - u'Каталог':{u'field': u'price_catalog', u'func': to_int}, - u'Налог включен':{u'field': u'tax', u'func': bool}, - u'Год основания':{u'field': u'foundation_year', u'func': to_int}, - #???u'Данные за год':{u'field': u'periodic', u'func': to_int}, - u'Посетители':{u'field': u'visitors', u'func': to_int}, - u'Участники':{u'field': u'members', u'func': to_int}, - u'Страны':{u'field': u'stat_countries', u'func': unicode}, - u'Площадь':{u'field': u'area', u'func': to_int}, - u'Мин стоимость':{u'field': u'min_price', u'func': to_int}, - u'Макс стоимость':{u'field': u'max_price', u'func': to_int}, - u'Min_Raw кв.м.':{u'field': u'min_closed_area', u'func': to_int}, - u'Max_Raw кв.м.':{u'field': u'max_closed_area', u'func': to_int}, - u'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int}, - u'Max_Pack кв.м.':{u'field': u'max_closed_equipped_area', u'func': to_int}, - u'Открытая площадь':{u'field': u'max_open_area', u'func': to_int}, - u'Мин. Площадь кв.м.':{u'field': u'min_stand_size', u'func': to_int}, - u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int}, - u'Примечание по участии':{u'field': u'participation_note', u'func': unicode}, - u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date}, - u'UFI':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'ufi'}, - u'РСВЯ':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'rsva'}, - u'EXPORATING':{u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'exporating'}, - u'Отменена':{u'field': u'canceled', u'func': bool}, - u'ExpoHIT':{u'field': u'expohit', u'func': bool}, + u'Валюта': {u'field': u'currency', u'func': unicode}, + u'Стоимость билета 1 день': {u'field': u'price_day', u'func': unicode}, + u'Стоимость билета все дни': {u'field': u'price_all', u'func': unicode}, + u'Условия предварительной регистрации': {u'field': u'pre_condition', u'func': unicode}, + u'Стоимость на стойке 1 день': {u'field': u'price_day_bar', u'func': unicode}, + u'Стоимость на стойке все дни': {u'field': u'price_all_bar', u'func': unicode}, + u'Условия регистрации на стойке': {u'field': u'stand_condition', u'func': unicode}, + u'Примечание по посещению': {u'field': u'visit_note', u'func': unicode}, + u'Каталог': {u'field': u'price_catalog', u'func': to_int}, + u'Налог включен': {u'field': u'tax', u'func': bool}, + u'Год основания': {u'field': u'foundation_year', u'func': to_int}, + u'Посетители': {u'field': u'visitors', u'func': to_int}, + u'Участники': {u'field': u'members', u'func': to_int}, + u'Страны': {u'field': u'stat_countries', u'func': unicode}, + u'Площадь': {u'field': u'area', u'func': to_int}, + u'Мин стоимость': {u'field': u'min_price', u'func': to_int}, + u'Макс стоимость': {u'field': u'max_price', u'func': to_int}, + u'Min_Raw кв.м.': {u'field': u'min_closed_area', u'func': to_int}, + u'Max_Raw кв.м.': {u'field': u'max_closed_area', u'func': to_int}, + u'Min_Pack кв.м.': {u'field': u'min_closed_equipped_area', u'func': to_int}, + u'Max_Pack кв.м.': {u'field': u'max_closed_equipped_area', u'func': to_int}, + u'Открытая площадь': {u'field': u'max_open_area', u'func': to_int}, + u'Мин. Площадь кв.м.': {u'field': u'min_stand_size', u'func': to_int}, + u'Регистрационный взнос': {u'field': u'registration_payment', u'func': to_int}, + u'Примечание по участии': {u'field': u'participation_note', u'func': unicode}, + u'Крайний срок подачи заявки': {u'field': u'application_deadline', u'func': to_date}, + u'UFI': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'ufi'}, + u'РСВЯ': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'rsva'}, + u'EXPORATING': {u'field': u'quality_label', u'func': check_quality_label, u'bitfield':True, u'label': 'exporating'}, + u'Отменена': {u'field': u'canceled', u'func': bool}, + u'ExpoHIT': {u'field': u'expohit', u'func': bool}, +} + +event_export_sett = [ + {'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500}, + {'name': 'url', 'verbose_name': u'Url', 'type': unicode}, + {'name': 'name', 'verbose_name': u'Название', 'type': unicode}, + {'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode}, + {'name': 'data_begin', 'verbose_name': u'Дата начала:(YYYY-MM-DD)', 'type': get_date}, + {'name': 'data_end', 'verbose_name': u'Дата окончания:(YYYY-MM-DD)', 'type': get_date}, + {'name': 'country', 'verbose_name': u'Страна', 'type': unicode}, + {'name': 'city', 'verbose_name': u'Город', 'type': unicode}, + {'name': 'place', 'verbose_name': u'Место проведения', 'type': get_place}, + {'name': 'theme', 'verbose_name': u'ID Тематики', 'type': get_theme, 'width':8000}, + {'name': 'tag', 'verbose_name': u'Теги', 'type': get_tag, 'width':8000}, + {'name': 'description', 'verbose_name': u'Описание события', 'type': unicode}, + {'name': 'org', 'verbose_name': u'Организатор №1', 'type': get_int}, + {'name': 'periodic', 'verbose_name': 'Периодичность', 'type': get_periodic}, + {'name': 'audience', 'verbose_name': u'Аудитория', 'type': get_audience}, + {'name': 'web_page', 'verbose_name': u'Официальный веб-сайт', 'type': unicode}, + {'name': 'products', 'verbose_name': u'Экспонируемые продукты', 'type': unicode}, + {'name': 'time', 'verbose_name': u'Время работы', 'type': unicode}, + {'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode}, + {'name': 'currency', 'verbose_name': u'Валюта', 'type': unicode}, + {'name': 'price_day', 'verbose_name': u'Стоимость билета 1 день', 'type': unicode}, + {'name': 'price_all', 'verbose_name': u'Стоимость билета все дни', 'type': unicode}, + {'name': 'pre_condition', 'verbose_name': u'Условия предварительной регистрации', 'type': unicode}, + {'name': 'price_day_bar', 'verbose_name': u'Стоимость на стойке 1 день', 'type': unicode}, + {'name': 'price_all_bar', 'verbose_name': u'Стоимость на стойке все дни', 'type': unicode}, + {'name': 'stand_condition', 'verbose_name': u'Условия регистрации на стойке', 'type': unicode}, + {'name': 'visit_note', 'verbose_name': u'Примечание по посещению', 'type': unicode}, + {'name': 'price_catalog', 'verbose_name': u'Каталог', 'type': get_int}, + {'name': 'tax', 'verbose_name': u'Налог включен', 'type': get_bool, 'width':1000}, + {'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int}, + {'name': 'visitors', 'verbose_name': u'Посетители', 'type': get_int}, + {'name': 'members', 'verbose_name': u'Участники', 'type': get_int}, + #{'name': 'visit_note', 'verbose_name': u'Страны', 'type': unicode}, !!! delete from import + {'name': 'area', 'verbose_name': u'Площадь', 'type': get_int}, + {'name': 'min_closed_area', 'verbose_name': u'Min_Raw кв.м.', 'type': get_int}, + {'name': 'max_closed_area', 'verbose_name': u'Max_Raw кв.м.', 'type': get_int}, + {'name': 'min_closed_equipped_area', 'verbose_name': u'Min_Pack кв.м.', 'type': get_int}, + {'name': 'max_closed_equipped_area', 'verbose_name': u'Max_Pack кв.м.', 'type': get_int}, + {'name': 'max_open_area', 'verbose_name': u'Открытая площадь', 'type': get_int}, + {'name': 'min_stand_size', 'verbose_name': u'Мин. Площадь кв.м.', 'type': get_int}, + {'name': 'registration_payment', 'verbose_name': u'Регистрационный взнос', 'type': get_int}, + {'name': 'participation_note', 'verbose_name': u'Примечание по участии', 'type': unicode}, + {'name': 'application_deadline', 'verbose_name': u'Крайний срок подачи заявки', 'type': get_date}, + {'name': 'quality_label', 'verbose_name': u'UFI', 'type': get_quality}, #???? + {'name': 'quality_label', 'verbose_name': u'РСВЯ', 'type': get_quality},#??? + {'name': 'quality_label', 'verbose_name': u'EXPORATING', 'type': get_quality}, #??? + {'name': 'canceled_by_administrator', 'verbose_name': u'Отменена администратором', 'type': get_bool}, + {'name': 'expohit', 'verbose_name': u'ExpoHIT', 'type': get_bool}, + {'name': 'is_published', 'verbose_name': u'Опубликована', 'type': get_bool}, +] +# -----------------------END EVENT SETTINGS --------------------------------- + +# --------------PLACE EXPO SETTINGS----------------------------- + +# import +place_exp_sett = { + u'ID': {u'field': u'id', u'func': to_int}, + u'Название': {u'field': u'name', u'func': unicode}, + u'Тип': {u'field': u'type', u'func': to_type}, + u'Краткое описание': {u'field': u'main_title', u'func': unicode}, + u'Страна': {u'field': u'country', u'func': to_country}, + u'Город': {u'field': u'city_id', u'func': to_city, 'extra_values': 'country'}, + u'Описание': {u'field': u'description', u'func': unicode}, + u'Адрес': {u'field': u'adress', u'func': unicode}, + u'Тел.': {u'field': u'phone', u'func': to_phone}, + u'Факс': {u'field': u'fax', u'func': to_phone}, + u'Лого': {u'field': u'logo', u'func': save_logo, u'method': True}, + u'Веб-сайт': {u'field': u'web_page', u'func': unicode}, + u'Email': {u'field': u'email', u'func': unicode}, + u'Карта проезда': {u'field': u'map', u'func': save_file, u'method': True, u'purpose': 'map'}, + u'Виртуальный тур': {u'field': u'virtual_tour', u'func': to_url}, + u'Год основания': {u'field': u'foundation_year', u'func': to_int}, + u'Количество мероприятий в год': {u'field': u'event_in_year', u'func': to_int}, + u'Общая выставочная площадь, кв. м.': {u'field': u'total_area', u'func': to_int}, + u'Закрытая выставочная площадь, кв. м.': {u'field': u'closed_area', u'func': to_int}, + u'Открытая выставочная площадь, кв. м.': {u'field': u'open_area', u'func': to_int}, + u'Количество павильонов': {u'field': u'total_pavilions', u'func': to_int}, + u'Площадь павильона': {u'field': u'halls', u'func': save_halls, u'method': True}, + u'Конференц-залы': {u'field': u'total_halls', u'func': to_int}, + u'Схема территории': {u'field': u'scheme', u'func': save_file, u'method': True, u'purpose': 'scheme teritory'},#сделать + u'Банк/Банкоматы/Обмен валюты': {u'field': u'bank', u'func': bool}, + u'Детская комната': {u'field': u'children_room', u'func': bool}, + u'Сервис для людей с ограниченными физическими возможностями': {u'field': u'disabled_service', u'func': bool}, + u'Конгресс-центр': {u'field': u'conference_centre', u'func': bool}, + u'Бизнес-центр': {u'field': u'business_centre', u'func': bool}, + u'On-line регистрация': {u'field': u'online_registration', u'func': bool}, + u'Wi-Fi': {u'field': u'wifi', u'func': bool}, + u'Кафе и рестораны': {u'field': u'cafe', u'func': bool}, + u'Информационные терминалы': {u'field': u'terminals', u'func': bool}, + u'Парковка': {u'field': u'parking', u'func': bool}, + u'Пресс-центр': {u'field': u'press_centre', u'func': bool}, + u'Мобильное приложение': {u'field': u'mobile_application', u'func': bool}, + # place_conf settings + u'Мультимедийное оборудование': {u'field': u'multimedia_equipment', u'func': bool}, + u'Конференц-связь': {u'field': u'conference_call', u'func': bool}, + u'Оборудование для синхронного перевода': {u'field': u'translate_equipment', u'func': bool}, + u'Банкетный зал': {u'field': u'banquet_hall', u'func': bool}, + u'Кейтеринг': {u'field': u'catering', u'func': bool}, + u'Гостиница': {u'field': u'hotel', u'func': bool}, + u'Выставочный зал': {u'field': u'exposition_hall', u'func': bool}, + u'Площадь выст. зала': {u'field': u'exp_hall_area', u'func': to_int}, + u'Общая вместимость': {u'field': u'total_capacity', u'func': to_int}, + u'Количество залов': {u'field': u'amount_halls', u'func': bool}, } +# export +place_settings=[ + {'name': 'id', 'verbose_name': u'ID', 'type': get_int, 'width':1500}, + {'name': 'url', 'verbose_name': u'Url', 'type': unicode}, + {'name': 'name', 'verbose_name': u'Название', 'type': unicode}, + {'name': 'type', 'verbose_name': u'Тип', 'type': get_place_type},########## + {'name': 'main_title', 'verbose_name': u'Краткое описание', 'type': unicode}, + {'name': 'country', 'verbose_name': u'Страна', 'type': unicode}, + {'name': 'city', 'verbose_name': u'Город', 'type': unicode}, + {'name': 'adress', 'verbose_name': u'Адресс', 'type': unicode}, + {'name': 'phone', 'verbose_name': u'Тел.', 'type': get_int}, + {'name': 'fax', 'verbose_name': u'Факс', 'type': get_int}, + {'name': 'logo', 'verbose_name': u'Логотип', 'type': unicode}, + {'name': 'web_page', 'verbose_name': u'Веб-сайт', 'type': unicode}, + {'name': 'email', 'verbose_name': u'Email', 'type': unicode}, + {'name': 'virtual_tour', 'verbose_name': u'Виртуальный тур', 'type': unicode}, + {'name': 'foundation_year', 'verbose_name': u'Год основания', 'type': get_int}, + {'name': 'event_in_year', 'verbose_name': u'Количество мероприятий в год', 'type': get_int}, + {'name': 'total_area', 'verbose_name': u'Общая выставочная площадь, кв. м.', 'type': get_int}, + {'name': 'closed_area', 'verbose_name': u'Закрытая выставочная площадь, кв. м.', 'type': get_int}, + {'name': 'open_area', 'verbose_name': u'Открытая выставочная площадь, кв. м.', 'type': get_int}, + {'name': 'total_pavilions', 'verbose_name': u'Количество павильонов', 'type': get_int}, + {'name': 'total_halls', 'verbose_name': u'Конференц-залы', 'type': get_int}, + {'name': 'total_capacity', 'verbose_name': u'Общая вместимость', 'type': get_int}, + {'name': 'exposition_hall', 'verbose_name': u'Выставочный зал', 'type': get_bool}, + {'name': 'exp_hall_area', 'verbose_name': u'Площадь выст. зала', 'type': get_int}, + {'name': 'amount_halls', 'verbose_name': u'Количество залов', 'type': get_int}, + {'name': 'bank', 'verbose_name': u'Банк/Банкоматы/Обмен валюты', 'type': get_bool}, + {'name': 'children_room', 'verbose_name': u'Детская комната', 'type': get_bool}, + {'name': 'disabled_service', 'verbose_name': u'Сервис для людей с ограниченными физическими возможностями', 'type': get_bool}, + {'name': 'conference_centre', 'verbose_name': u'Конгресс-центр', 'type': get_bool}, + {'name': 'business_centre', 'verbose_name': u'Бизнес-центр', 'type': get_bool}, + {'name': 'online_registration', 'verbose_name': u'On-line регистрация', 'type': get_bool}, + {'name': 'wifi', 'verbose_name': u'Wi-Fi', 'type': get_bool}, + {'name': 'cafe', 'verbose_name': u'Кафе и рестораны', 'type': get_bool}, + {'name': 'terminals', 'verbose_name': u'Информационные терминалы', 'type': get_bool}, + {'name': 'parking', 'verbose_name': u'Парковка', 'type': get_bool}, + {'name': 'press_centre', 'verbose_name': u'Пресс-центр', 'type': get_bool}, + {'name': 'mobile_application', 'verbose_name': u'Мобильное приложение', 'type': get_bool}, + {'name': 'multimedia_equipment', 'verbose_name': u'Мультимедийное оборудование', 'type': get_bool}, + {'name': 'conference_call', 'verbose_name': u'Конференц-связь', 'type': get_bool}, + {'name': 'translate_equipment', 'verbose_name': u'Оборудование для синхронного перевода', 'type': get_bool}, + {'name': 'banquet_hall', 'verbose_name': u'Банкетный зал', 'type': get_bool}, + {'name': 'catering', 'verbose_name': u'Кейтеринг', 'type': get_bool}, + {'name': 'hotel', 'verbose_name': u'Гостиница', 'type': get_bool}, + +] +# -----------------END PLACE EXPO SETTINGS------------------------------ +# default import settings import_settings={ 'name': {'func': unicode}, 'url': {'func': unicode}, diff --git a/import_xls/export_forms.py b/import_xls/export_forms.py index 363c9ba3..4f1bf333 100644 --- a/import_xls/export_forms.py +++ b/import_xls/export_forms.py @@ -13,7 +13,7 @@ from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference from django.db.models.loading import get_model import xlwt -from excel_settings import import_settings, field_settings, event_export_sett +from excel_settings import field_settings, event_export_sett languages = [code for code in settings.LANGUAGES] @@ -75,13 +75,6 @@ class ExportForm(forms.Form): return self.workbook - -class ExportOrganiserForm(ExportForm): - model = Organiser - - def get_fname(self): - return 'organisers.xls' - class ExportUserForm(ExportForm): model = User @@ -106,7 +99,9 @@ class ExportTagForm(ExportForm): from excel_settings import place_settings class ExportPlaceExpositionForm(ExportForm): + model = PlaceExposition + def export(self): data = self.cleaned_data objects = self.get_objects(data) @@ -130,21 +125,18 @@ class ExportPlaceExpositionForm(ExportForm): self.worksheet.write(0, col, field.get('verbose_name', 'default'), self.style) #self.worksheet.write(1, col, field.get('name'), self.style) self.worksheet.col(col).width = field.get('width', 3333) - if field['name']=='tag': - self.worksheet.write(row+1, col, field.get('type')(value, object.theme)) - else: - self.worksheet.write(row+1, col, field.get('type')(value)) + + self.worksheet.write(row+1, col, field.get('type')(value)) + col += 1 return self.workbook def get_fname(self): return 'places.xls' -class ExportPlaceConferenceForm(ExportForm): +class ExportPlaceConferenceForm(ExportPlaceExpositionForm): model = PlaceConference - def get_fname(self): - return 'places.xls' class ExportCompanyForm(ExportForm): model = Company diff --git a/import_xls/import_forms.py b/import_xls/import_forms.py index 8554605c..cf948bf8 100644 --- a/import_xls/import_forms.py +++ b/import_xls/import_forms.py @@ -1,18 +1,32 @@ # -*- coding: utf-8 -*- +import urllib +import json +import xlrd +from django.db import IntegrityError from django import forms from django.conf import settings +from django.db.models.loading import get_model from theme.models import Theme, Tag from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference -from country.models import Country -from organiser.models import Organiser -from django.db.models.loading import get_model -import xlrd, xlwt +from import_xls.models import Log from excel_settings import import_settings from functions.form_check import translit_with_separator +from excel_settings import place_exp_sett +from import_xls.excel_settings import event_sett languages = [code for code in settings.LANGUAGES] +typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город', + '(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город', + '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания', + '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'} + + +def logcall(f, msg): + with open(f.file.name, 'a') as logfile: + logfile.write(msg.encode('utf8')) + class ImportForm(forms.Form): """ @@ -82,19 +96,11 @@ class ImportForm(forms.Form): object.save() -class ImportOrganiserForm(ImportForm): - model = Organiser - class ImportThemeForm(ImportForm): model = Theme -from excel_settings import place_exp_sett -from django.db import IntegrityError -import urllib, json - - def google_address(address): if address: address = address.encode('utf') @@ -112,13 +118,131 @@ def google_address(address): return '' return '' -from djutils.decorators import async -from djutils.queue.decorators import queue_command + # place class ImportPlaceExpositionForm(ImportForm): model = PlaceExposition settings = place_exp_sett + def get_row_object(self, row): + if row[0] != '': + # in first column id + try: + obj = self.model.objects.language(self.lang).get(id=int(row[0])) + except ValueError: + obj = self.model() + obj.translate(self.lang) + + except self.model.DoesNotExist: + obj = self.model(id= int(row[0])) + obj.translate(self.lang) + else: + # if id blank - its a new object + obj = self.model() + obj.translate(self.lang) + return obj + + + + def save_file_debug(self): + data = self.cleaned_data + lang, self.lang = data['language'], data['language'] + f = data['excel_file'] + book = xlrd.open_workbook(file_contents=f.read()) + sheet = book.sheet_by_index(0) + row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] + field_names = [name for name in row_list[0]] + model = self.model + labels = [label for label in row_list[0]] + errors = [] + + #log = Log.custom.create_log_name(f) + for row_number, row in enumerate(row_list): + if row_number == 0: + continue + #log_msg = u'[%s] %s: '%(str(row_number), row[2]) + obj = self.get_row_object(row) + methods = [] + # go through row cells + for col_number, cell in enumerate(row): + # get current label + label = labels[col_number] + + setting = event_sett.get(label) + if setting is None: + # no label in settings + continue + + if setting.get('method'): + # this cell contains data that must be written after creating object + if cell != "": + methods.append({'func': setting['func'], 'value': cell, + 'purpose': setting.get('purpose'), 'field': label}) + continue + + field_name = setting['field'] + func = setting.get('func') + if func is None: + # no function in settings + continue + + extra_value = setting.get('extra_values') + if extra_value is not None: + # if setting has extra value then + # it is some field like city, tag + # that has relation and can be created + + # in function we add language(need for relation fields) + # and extra value from object (like for city need country) + try: + extra = getattr(obj, extra_value) + except Exception: + continue + value = func(cell, 'ru', extra) + else: + value = func(cell) + + #try: + setattr(obj, field_name, value) + #except ValueError: + # continue + + if not obj.url: + obj.url = translit_with_separator(obj.name) + + # try: + obj.save() + # except IntegrityError, e: + # error = str(e) + # if typical_errors.get(error): + # error = typical_errors[error] + # if error.startswith('(1062, "Duplicate entry') and error.endswith('for key \'url\'")'): + # + # error = u'Событие с таким названием или урлом уже существует' + # + # errors.append([obj.name, error]) + # log_msg += error + # logcall(log.log, log_msg + '\n') + # continue + + for method in methods: + func = method['func'] + if method.get('purpose'): + try: + func(obj, method['value'], method['purpose']) + except: + #log_msg += '(%s: Ошибка);'%method['field'] + continue + else: + msg = func(obj, method['value']) + if msg: + #log_msg += '(%s: %s);'%(method['field'], msg) + pass + + #logcall(log.log, log_msg + '\n') + + + def save_file(self): data = self.cleaned_data lang = data['language'] @@ -234,27 +358,10 @@ class ImportPlaceExpositionForm(ImportForm): return errors - -class ImportPlaceConferenceForm(ImportForm): +class ImportPlaceConferenceForm(ImportPlaceExpositionForm): model = PlaceConference -from import_xls.excel_settings import event_sett -typical_errors = {'(1048, "Column \'city_id\' cannot be null")':u'Неправильная страна или город', - '(1048, "Column \'country_id\' cannot be null")':u'Неправильная страна или город', - '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата окончания', - '(1048, "Column \'data_end\' cannot be null")':u'НЕправильный формат или не заполнена дата начала'} - -# 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): """ extended form for importing one type of event @@ -359,8 +466,8 @@ class ImportEventForm(ImportForm): except Exception: setattr(obj, 'place_alt', cell) if not obj.url: - a = obj.name obj.url = translit_with_separator(obj.name) + obj.is_published = True try: obj.save() diff --git a/place_conference/admin.py b/place_conference/admin.py index 9fc3f793..1202bd5f 100644 --- a/place_conference/admin.py +++ b/place_conference/admin.py @@ -189,6 +189,63 @@ def conference_change(request, url): return render_to_response('place_conference_add.html', args) +from photologue.forms import PhotoForm +from functions.admin_views import AdminView +from file.forms import FileModelForm, FileForm +class PlaceConferenceView(AdminView): + form_class = ConferenceForm + model = PlaceConference + success_url = '/admin/place_conference/all/' + template_name = 'admin/place_conference/place_conference.html' + + def get_form(self, form_class): + if self.request.POST: + return super(PlaceConferenceView, self).get_form(form_class) + obj = self.set_obj() + if obj: + data = {'type': obj.type, 'address': obj.address, + 'phone': obj.phone, 'fax': obj.fax, 'web_page': obj.web_page, 'email': obj.email, + 'foundation_year': obj.foundation_year, 'total_capacity': obj.total_capacity, + 'amount_halls': obj.amount_halls, 'wifi':obj.wifi, 'multimedia_equipment': obj.multimedia_equipment, + 'conference_call':obj.conference_call, 'translate_equipment': obj.translate_equipment, + 'banquet_hall': obj.banquet_hall, 'catering': obj.catering, 'hotel': obj.hotel, + 'video_link':obj.video_link, 'logo': obj.logo, 'exposition_hall': obj.exposition_hall, + 'exp_hall_area': obj.exp_hall_area} + + data['country'] = obj.country_id + data['city'] = obj.city_id + + for code, name in settings.LANGUAGES: + trans_obj = self.model._meta.translations_model.objects.get(language_code = code,master__id=obj.id) #access to translated fields + data['name_%s'%code] = obj.name + data['main_title_%s'%code] = obj.main_title + data['description_%s'%code] = obj.description + data['adress_%s'%code] = obj.adress + data['hall_capacity_%s'%code] = obj.hall_capacity + data['title_%s'%code] = obj.title + data['keywords_%s'%code] = obj.keywords + data['descriptions_%s'%code] = obj.descriptions + data['total_year_action_%s'%code] = obj.total_year_action + + form = form_class(initial=data) + form.fields['city'].widget.attrs['data-init-text'] = obj.city.name + return form + else: + return form_class() + + + def get_context_data(self, **kwargs): + context = super(PlaceConferenceView, self).get_context_data(**kwargs) + obj = self.set_obj() + if obj: + context['file_form'] = FileForm(initial={'model': 'place_conference.PlaceConference'}) + files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id')) + context['files'] = files + + context['photo_form'] = PhotoForm() + + return context + class PlaceConferenceListView(AdminListView): template_name = 'admin/place_conference/place_conference_list.html' form_class = PlaceConferenceFilterForm diff --git a/place_conference/admin_urls.py b/place_conference/admin_urls.py index aa45ae8a..4816e171 100644 --- a/place_conference/admin_urls.py +++ b/place_conference/admin_urls.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url -from admin import PlaceConferenceListView +from admin import PlaceConferenceListView, PlaceConferenceView urlpatterns = patterns('place_conference.admin', url(r'^add.*/$', 'conference_add'), @@ -9,4 +9,6 @@ urlpatterns = patterns('place_conference.admin', url(r'^copy/(?P.*)/$', 'place_conference_copy'), #url(r'^all/$', 'conference_all'), url(r'^all/$', PlaceConferenceListView.as_view()), + url(r'^(?P.*)/$', PlaceConferenceView.as_view()), + url(r'^$', PlaceConferenceView.as_view()), ) diff --git a/place_conference/forms.py b/place_conference/forms.py index 94b1dee6..f2e38aa5 100644 --- a/place_conference/forms.py +++ b/place_conference/forms.py @@ -28,12 +28,12 @@ class ConferenceForm(forms.Form): """ types = [(item1, item2) for item1, item2 in CONFERENCE_TYPE] type = forms.ChoiceField(label='Краткое описание', required=False, choices=types) - + logo = forms.ImageField(label='Logo', required=False, max_length=500) country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None) #creates select input with empty choices cause it will be filled with ajax - city = forms.ChoiceField(label='Город', choices=[('','')]) + city = forms.CharField(label='Город', widget=forms.HiddenInput()) - address = forms.CharField(label='Адресс', widget=LocationWidget) + address = forms.CharField(label='Адресс', widget=LocationWidget, required=False) foundation_year = forms.CharField(label='Год основания', required=False, widget=forms.TextInput(attrs={'placeholder': 'Год основания'})) phone = forms.CharField(label='Телефон', required=False, @@ -108,7 +108,7 @@ class ConferenceForm(forms.Form): """ - def save(self, id=None): + def save(self, obj=None): """ change PlaceConference model object with id = id N/A add new PlaceConference model object @@ -117,13 +117,20 @@ class ConferenceForm(forms.Form): """ data = self.cleaned_data #create new place_conference object or get exists - if not id: + if not obj: place_conference = PlaceConference() else: - place_conference = PlaceConference.objects.get(id=id) + place_conference = obj + + if not getattr(place_conference, 'url'): + if data.get('name_en'): + place_conference.url = translit_with_separator(data['name_en'].strip()).lower() + else: + place_conference.url = translit_with_separator(data['name_ru'].strip()).lower() + if data.get('logo'): + place_conference.logo = data['logo'] #simple fields - place_conference.url = translit_with_separator(data['name_ru'].strip()).lower() place_conference.type = data['type'] place_conference.address = data['address'] place_conference.phone = data['phone'] @@ -152,22 +159,9 @@ class ConferenceForm(forms.Form): fill_with_signal(PlaceConference, place_conference, data) #save files - check_tmp_files(place_conference, data['key']) - - return PlaceConference.objects.get(id=place_conference.id) - - def clean(self): - id = self.cleaned_data.get('place_conference_id') - name_ru = self.cleaned_data.get('name_ru') - - place_conference = PlaceConference.objects.filter(url=translit_with_separator(name_ru)) - if place_conference and str(place_conference[0].id) != id: - msg = 'Место проведения с таким названием уже существует' - self._errors['name_ru'] = ErrorList([msg]) - del self.cleaned_data['name_ru'] - - return self.cleaned_data + place_conference.save() + return place_conference def clean_web_page(self): """ @@ -318,4 +312,17 @@ class HallForm(forms.ModelForm): class PlaceConferenceFilterForm(AdminFilterForm): - model = PlaceConference \ No newline at end of file + model = PlaceConference + + country = forms.MultipleChoiceField(choices=[(item.id, item.name) for item in list(Country.objects.all())], + required=False, widget=forms.SelectMultiple()) + + def filter(self): + qs = super(PlaceConferenceFilterForm, self).filter() + data = self.cleaned_data + country = data['country'] + + if country: + qs = qs.filter(country_id__in=country) + + return qs \ No newline at end of file diff --git a/place_conference/models.py b/place_conference/models.py index 170a8806..03fe4f1b 100644 --- a/place_conference/models.py +++ b/place_conference/models.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- from django.db import models from django.contrib.contenttypes import generic -from django.db.models.signals import post_save +from django.db.models.signals import post_save, pre_save from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from functions.custom_fields import EnumField from functions.custom_fields import LocationField -from functions.signal_handlers import post_save_handler +from functions.signal_handlers import post_save_handler, pre_save_handler from functions.models_methods import ExpoManager import copy from django.utils.translation import ugettext as _ @@ -15,6 +15,11 @@ from functions.model_mixin import ExpoMixin CONFERENCE_TYPE = (('Convention centre', 'Конгресс-центр'), ('Exposition centre', 'Конференц зал'),) +def logo_name(instance, filename): + url = instance.url + return '/'.join(['place_conference', url, url+'_logo.jpg']) + + class PlaceConference(TranslatableModel, ExpoMixin): """ Create PlaceConference model @@ -22,28 +27,33 @@ class PlaceConference(TranslatableModel, ExpoMixin): Uses hvad.TranslatableModel which is child of django.db.models class """ - #set manager of this model + catalog = '/places/' + place = 'place_conference' + catalog_name = _(u'Места:') + search_name = None objects = ExpoManager() url = models.SlugField(unique=True) - country = models.ForeignKey('country.Country', on_delete=models.PROTECT) - city = models.ForeignKey('city.City', on_delete=models.PROTECT, related_name='place_conferences') + country = models.ForeignKey('country.Country', on_delete=models.PROTECT, verbose_name=_(u'Страна')) + city = models.ForeignKey('city.City', on_delete=models.PROTECT, + related_name='place_conferences', verbose_name=_(u'Город')) #type uses EnumField for creating Enum type field in Mysql database - type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE]) + type = EnumField(values = [item1 for item1, item2 in CONFERENCE_TYPE], default=CONFERENCE_TYPE[0][0], + verbose_name=_(u'Тип')) #information + address = LocationField(verbose_name=_(u'Адресс')) # - address= LocationField(verbose_name='Адресс') - # - phone = models.BigIntegerField(blank=True, null=True) - fax = models.BigIntegerField(blank=True, null=True) - web_page = models.URLField(blank=True) - email = models.EmailField(blank=True) - foundation_year = models.PositiveIntegerField(blank=True, null=True) - total_capacity = models.PositiveIntegerField(blank=True, null=True) - amount_halls = models.PositiveIntegerField(blank=True, null=True) - exposition_hall = models.NullBooleanField() - exp_hall_area = models.PositiveIntegerField(blank=True, null=True) + phone = models.BigIntegerField(blank=True, null=True, verbose_name=_(u'Телефон')) + fax = models.BigIntegerField(blank=True, null=True, verbose_name=_(u'Факс')) + web_page = models.URLField(blank=True, verbose_name=_(u'Веб сайт')) + email = models.EmailField(blank=True, verbose_name=_(u'Email')) + foundation_year = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Год основания')) + total_capacity = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Общая вместимость')) + amount_halls = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Количество залов')) + exposition_hall = models.NullBooleanField(verbose_name=_(u'Выставочный зал')) + exp_hall_area = models.PositiveIntegerField(blank=True, null=True, verbose_name=_(u'Площадь выст. зала')) video_link = models.CharField(max_length=255, blank=True) + virtual_tour = models.URLField(blank=True, verbose_name=_(u'Виртуальный тур')) # wifi = models.NullBooleanField() multimedia_equipment = models.NullBooleanField() @@ -53,6 +63,7 @@ class PlaceConference(TranslatableModel, ExpoMixin): catering = models.NullBooleanField() hotel = models.NullBooleanField() # + logo = models.ImageField(verbose_name='Logo', upload_to=logo_name, blank=True, max_length=255) files = generic.GenericRelation('file.FileModel',content_type_field='content_type', object_id_field='object_id') #translations is translated fields translations = TranslatedFields( @@ -162,5 +173,5 @@ class Hall(models.Model): number = models.PositiveIntegerField(blank=True, null=True) capacity = models.PositiveIntegerField(blank=True, null=True) - +pre_save.connect(pre_save_handler, sender=PlaceConference) post_save.connect(post_save_handler, sender=PlaceConference) \ No newline at end of file diff --git a/place_exposition/forms.py b/place_exposition/forms.py index ad71fde8..c9b6cd6e 100644 --- a/place_exposition/forms.py +++ b/place_exposition/forms.py @@ -112,7 +112,7 @@ class ExpositionForm(forms.Form): else: place_exposition = obj - #simple fields + if not getattr(place_exposition, 'url'): if data.get('name_en'): place_exposition.url = translit_with_separator(data['name_en'].strip()).lower() @@ -252,30 +252,6 @@ class PlaceExpositionFormDelete(forms.ModelForm): model = PlaceExposition fields = ('url',) -''' -class HallForm(forms.ModelForm): - """ - form for Hall model - uses ModelForm cause Hall doesnt have translated fields - """ - number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:30px'}),required=False) - capacity = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:60px'}), required=False) - name = forms.CharField(required=False) - class Meta: - model = Hall - exclude = ('place_exposition',) - - def clean_number(self): - cleaned_data = super(HallForm, self).clean() - number = cleaned_data.get('number').strip() - return is_positive_integer(number, 'Номер должен состоять из цифр') - - def clean_capacity(self): - cleaned_data = super(HallForm, self).clean() - capacity = cleaned_data.get('capacity').strip() - return is_positive_integer(capacity, 'Вместимость должна состоять из цифр') - -''' class HallForm(forms.Form): url = '/admin/place_exposition/add-hall/' diff --git a/place_exposition/models.py b/place_exposition/models.py index 78b329d8..0db008e7 100644 --- a/place_exposition/models.py +++ b/place_exposition/models.py @@ -39,6 +39,7 @@ class PlaceExposition(TranslatableModel, ExpoMixin): """ catalog = '/places/' + place = 'place_exposition' catalog_name = _(u'Места:') search_name = None #set manager of this model @@ -289,17 +290,3 @@ def create_place(sender, instance, created, **kwargs): pre_save.connect(pre_save_handler, sender=PlaceExposition) post_save.connect(create_place, sender=PlaceExposition) post_save.connect(post_save_handler, sender=Hall) - - - - -""" -def calculate_rating_for_translations(sender, instance, created, **kwargs): - company = instance.master - post_save.disconnect(calculate_rating_for_translations, sender=Company._meta.translations_model) - calculate_rating(company) - post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model) - -post_save.connect(create_company, sender=Company) -post_save.connect(calculate_rating_for_translations, sender=Company._meta.translations_model) -""" \ No newline at end of file diff --git a/place_exposition/views.py b/place_exposition/views.py index ba8f939a..16115ccd 100644 --- a/place_exposition/views.py +++ b/place_exposition/views.py @@ -80,7 +80,7 @@ class PlaceDetail(JitterCacheMixin, MetadataMixin, DetailView): obj = queryset.get() except queryset.model.DoesNotExist: try: - PlaceConference.objects.get(url=slug) + obj = PlaceConference.objects.get(url=slug) except PlaceConference.DoesNotExist: raise Http404(_("No %(verbose_name)s found matching the query") % diff --git a/templates/admin/includes/admin_nav.html b/templates/admin/includes/admin_nav.html index 8de663b0..88070a6f 100644 --- a/templates/admin/includes/admin_nav.html +++ b/templates/admin/includes/admin_nav.html @@ -66,11 +66,8 @@ Импорт @@ -78,12 +75,11 @@ Экспорт diff --git a/templates/admin/place_conference/place_conference.html b/templates/admin/place_conference/place_conference.html new file mode 100644 index 00000000..70d37f4f --- /dev/null +++ b/templates/admin/place_conference/place_conference.html @@ -0,0 +1,340 @@ +{% extends 'base.html' %} +{% load static %} +{% block styles %} +.hover{ + display:none; + margin-bottom:10px; + +} +.photo:hover .hover { + display: block; +} +{% endblock %} + +{% block scripts %} + + + {# google map не забыть скачать скрипты на локал #} + + + + + {# selects #} + + + + + {# ajax #} + + + + +{% endblock %} + +{% block body %} + +
{% csrf_token %} +
+ {% if object %} Изменить {% else %} Добавить {% endif %}место{% if object %}(на сайте){% endif %} + +
+
+

Основная информация

+
+
+ + {# name #} + {% with field='name' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# type #} +
+ +
{{ form.type}} + {{ form.type.errors }} +
+
+ {# main_title #} + {% with field='main_title' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# country #} +
+ +
{{ form.country }} + {{ form.country.errors }} +
+
+ {# city #} +
+ +
{{ form.city }} + {{ form.city.errors }} +
+
+ + {# logo #} +
+ +
{{ form.logo }} + {{ form.logo.errors }} +
+
+ +
+
+ +
+
+

Дополнительная информация

+
+
+ {# description #} + {% with field='description' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# adress #} + {% with field='adress' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# address #} +
+ +
{{ form.address }} + {{ form.address.errors }} +
+
+ + {# phone #} +
+ +
{{ form.phone}} + {{ form.phone.errors }} +
+
+ {# fax #} +
+ +
{{ form.fax}} + {{ form.fax.errors }} +
+
+ {# web_page #} +
+ +
{{ form.web_page}} + {{ form.web_page.errors }} +
+
+ {# email #} +
+ +
{{ form.email}} + {{ form.email.errors }} +
+
+ + + +
+
+
+
+

Основная информация

+
+
+ {# foundation_year #} +
+ +
{{ form.foundation_year}} + {{ form.foundation_year.errors }} +
+
+ {# total_year_action #} + {% with field='total_year_action' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + + {# total_capacity #} +
+ +
{{ form.total_capacity}} + {{ form.total_capacity.errors }} +
+
+ + {# amount_halls #} +
+ +
{{ form.amount_halls}} + {{ form.amount_halls.errors }} +
+
+ + {# video_link #} +
+ +
{{ form.video_link}} + {{ form.video_link.errors }} +
+
+ {# exp_hall_area #} +
+ +
{{ form.exp_hall_area}} + {{ form.exp_hall_area.errors }} +
+
+ + +
+
+ + + +
+
+

Услуги

+
+
+
+ {# exposition_hall #} +
+ +
{{ form.exposition_hall}} + {{ form.exposition_hall.errors }} +
+
+ {# wifi #} +
+ +
{{ form.wifi}} + {{ form.wifi.errors }} +
+
+ {# catering #} +
+ +
{{ form.catering}} + {{ form.catering.errors }} +
+
+ {# hotel #} +
+ +
{{ form.hotel}} + {{ form.hotel.errors }} +
+
+ {# banquet_hall #} +
+ +
{{ form.banquet_hall}} + {{ form.banquet_hall.errors }} +
+
+ +
+
+ {# multimedia_equipment #} +
+ +
{{ form.multimedia_equipment}} + {{ form.multimedia_equipment.errors }} +
+
+ + {# translate_equipment #} +
+ +
{{ form.translate_equipment}} + {{ form.translate_equipment.errors }} +
+
+ {# conference_call #} +
+ +
{{ form.conference_call}} + {{ form.conference_call.errors }} +
+
+ +
+ +
+
+ +
+
+

Файлы

+
+
+ {% if object %} + {# button that shows modal window with file form #} + Добавить файл + {% else %} +

Файлы можно добавлять только после введения основных данных

+ {% endif %} + {# this div shows list of files and refreshes when new file added #} +
+ + + + + + + + + + + + + {% include 'file_list.html' with files=files %} + +
idФайлИмяНазначение
+
+ +
+
+ + {% include 'admin/includes/photogallery.html' with object=object %} + +
+
+

Мета данные

+
+
+ + {# keywords #} + {% with field='keywords' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# title #} + {% with field='title' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + {# descriptions #} + {% with field='descriptions' form=form languages=languages %} + {% include 'admin/forms/multilang.html' %} + {% endwith %} + +
+
+ + +
+ + +
+ +
+
+ + + + +{% include 'admin/includes/hall_form.html' with form=hall_form object=object %} +{% include 'admin/includes/photo_form.html' with form=photo_form object=object %} +{% include 'admin/includes/file_form.html' with file_form=file_form object=object %} + +{% endblock %} \ No newline at end of file diff --git a/templates/admin/place_conference/place_conference_list.html b/templates/admin/place_conference/place_conference_list.html index cd9c6233..b3f656ac 100644 --- a/templates/admin/place_conference/place_conference_list.html +++ b/templates/admin/place_conference/place_conference_list.html @@ -38,7 +38,7 @@ {% ifnotequal item.country None %}{{ item.country }} {% endifnotequal %} {% ifnotequal item.city None %}{{ item.city }} {% endifnotequal %} - + Изменить diff --git a/templates/client/includes/place/place_info.html b/templates/client/includes/place/place_info.html new file mode 100644 index 00000000..dc129a3d --- /dev/null +++ b/templates/client/includes/place/place_info.html @@ -0,0 +1,86 @@ +{% load i18n %} +{% load template_filters %} + +
+ + {% if place.place == 'place_exposition' %} + {% if place.total_area %} +
+
{% trans 'Общая выставочная площадь' %}
+
{{ place.total_area|int_format }} м²
+
+ {% endif %} + {% else %} + {% comment %} + {% if place.total_capacity %} +
+
{% trans 'Общая вместимость' %}
+
{{ place.total_capacity|int_format }}
+
+ {% endif %} + {% endcomment %} + {% endif %} + +
+ {% if place.closed_area %} +
+ {{ place.closed_area|int_format }} {% trans 'м²' %} + {% trans 'закрытая выставочная площадь' %} +
+ {% endif %} + {% if place.open_area %} +
+ {{ place.open_area|int_format }} {% trans 'м²' %} + {% trans 'открытая выставочная площадь' %} +
+ {% endif %} +
+
+
+
    + {% for hall in place.halls.all %} + {% if not forloop.counter|divisibleby:"2" %} +
  • {{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м2
  • + {% endif %} + {% endfor %} +
+
+
+
    + {% for hall in place.halls.all %} + {% if forloop.counter|divisibleby:"2" %} +
  • {{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м2
  • + {% endif %} + {% endfor %} +
+
+
+ + {% if place.total_year_action %} +
+
+ {% trans 'Ежегодно проводится' %} +
+
+ {% if place.total_year_action.isdigit %} + {% ifequal LANGUAGE_CODE 'ru' %} + {% load pymorphy_tags %} + {{ place.total_year_action }} + {{ "событие"|plural:place.total_year_action }} + {% else %} + {{ place.total_year_action }} + {% trans 'событий' %} + {% endifequal %} + + {% else %} + {{ place.total_year_action }} + {% endif %} +
+
+ {% endif %} + {% if place.foundation_year %} +
+
{% trans 'Основано в' %} {{ place.foundation_year }} {% trans 'году' %}
+
+ {% endif %} +
\ No newline at end of file diff --git a/templates/client/includes/place/place_object.html b/templates/client/includes/place/place_object.html index 4be3f158..10bb632a 100644 --- a/templates/client/includes/place/place_object.html +++ b/templates/client/includes/place/place_object.html @@ -27,10 +27,10 @@
{{ place.adress }}
- + @@ -41,53 +41,7 @@ -
-
Услуги
-
-
    - {% if place.bank %} -
  • {% trans 'Банк / банкоматы / обмен валюты' %}
  • - {% endif %} - {% if place.wifi %} -
  • Wi-Fi
  • - {% endif %} - {% if place.children_room %} -
  • {% trans 'Детская комната' %}
  • - {% endif %} - {% if place.disabled_service %} -
  • {% trans 'Сервис для инвалидов' %}
  • - {% endif %} -
-
    - {% if place.conference_centre %} -
  • {% trans 'Конгресс-центр' %}
  • - {% endif %} - {% if place.business_centre %} -
  • {% trans 'Бизнес-центр' %}
  • - {% endif %} - {% if place.online_registration %} -
  • {% trans 'Онлайн-регистрация' %}
  • - {% endif %} - {% if place.cafe %} -
  • {% trans 'Кафе и рестораны' %}
  • - {% endif %} -
-
    - {% if place.terminals %} -
  • {% trans 'Информационные терминалы' %}
  • - {% endif %} - {% if place.parking %} -
  • {% trans 'Парковка' %}
  • - {% endif %} - {% if place.press_centre %} -
  • {% trans 'Пресс-центр' %}
  • - {% endif %} - {% if place.mobile_application %} -
  • {% trans 'Мобильное приложение' %}
  • - {% endif %} -
-
-
+ {% include 'client/includes/place/place_services.html' with place=place %}
{% if place.photogallery %} {% with photos=place.photogallery.photos.all|slice:"5" %} @@ -109,228 +63,162 @@ {% endwith %} {% endif %} -
- {% if place.total_area %} -
-
{% trans 'Общая выставочная площадь' %}
-
{{ place.total_area|int_format }} м²
-
- {% endif %} -
- {% if place.closed_area %} -
- {{ place.closed_area|int_format }} {% trans 'м²' %} - {% trans 'закрытая выставочная площадь' %} -
- {% endif %} - {% if place.open_area %} -
- {{ place.open_area|int_format }} {% trans 'м²' %} - {% trans 'открытая выставочная площадь' %} -
- {% endif %} -
-
-
-
    - {% for hall in place.halls.all %} - {% if not forloop.counter|divisibleby:"2" %} -
  • {{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м2
  • - {% endif %} - {% endfor %} -
-
-
-
    - {% for hall in place.halls.all %} - {% if forloop.counter|divisibleby:"2" %} -
  • {{ hall.name }} {% if hall.number %} №{{ hall.number }} {% endif %} — {{ hall.capacity }} м2
  • - {% endif %} - {% endfor %} -
-
-
-
- {% if place.total_year_action %} -
-
- {% trans 'Ежегодно проводится' %} -
-
- {% if place.total_year_action.isdigit %} - {% ifequal LANGUAGE_CODE 'ru' %} - {% load pymorphy_tags %} - {{ place.total_year_action }} - {{ "событие"|plural:place.total_year_action }} - {% else %} - {{ place.total_year_action }} - {% trans 'событий' %} - {% endifequal %} + {% include 'client/includes/place/place_info.html' with place=place %} + + {% if place.get_scheme %} +
+
+
{% trans 'Схема павильонов' %}
+ {% for scheme in place.get_scheme %} + {% ifequal scheme.file_path.url|slice:"-3:" 'pdf' %} + {% trans 'Схема в pdf' %} {% else %} - {{ place.total_year_action }} - {% endif %} -
+
+ {% endifequal %} +
+ {% endfor %}
{% endif %} - {% if place.foundation_year %} -
-
{% trans 'Основано в' %} {{ place.foundation_year }} {% trans 'году' %}
-
- {% endif %} -
- {% if place.get_scheme %} -
-
-
{% trans 'Схема павильонов' %}
- {% for scheme in place.get_scheme %} - {% ifequal scheme.file_path.url|slice:"-3:" 'pdf' %} - {% trans 'Схема в pdf' %} - {% else %} -
- {% endifequal %} -
- {% endfor %} -
- {% endif %} -
-
{% trans 'Контактная информация' %}
-
-
-
{{ place.adress }}
- - {% if place.events %} -
-
{% trans 'Список событий' %}
- -
- {% endif %} -
- {% include 'client/includes/booking_block.html' with city=place.city place=place %} -
-
-
- {% include 'client/includes/banners/detail_inner.html' %} -
- {% if place.get_nearest_places %} -
-
{% trans 'Ближайшие выставочные центры' %}
- +
+ {% endif %} +
+ {% include 'client/includes/booking_block.html' with city=place.city place=place %} +
+
+
+ {% include 'client/includes/banners/detail_inner.html' %} +
+ {% if place.get_nearest_places %} +
+
{% trans 'Ближайшие выставочные центры' %}
+ -
- {% endif %} - {% include 'client/includes/banners/detail_inner_3.html' %} +
+
+ {% if pl.total_area %} +
{{ pl.total_area }}
+ {% endif %} + +
+
+
+ + {% endfor %} + + + {% endif %} + {% include 'client/includes/banners/detail_inner_3.html' %} + {% endblock %} {% block scripts %} diff --git a/templates/client/includes/place/place_services.html b/templates/client/includes/place/place_services.html new file mode 100644 index 00000000..e4839e1d --- /dev/null +++ b/templates/client/includes/place/place_services.html @@ -0,0 +1,80 @@ +{% load i18n %} + +
+
{% trans 'Услуги' %}
+
+ {% if place.place == 'place_exposition' %} +
    + {% if place.bank %} +
  • {% trans 'Банк / банкоматы / обмен валюты' %}
  • + {% endif %} + {% if place.wifi %} +
  • Wi-Fi
  • + {% endif %} + {% if place.children_room %} +
  • {% trans 'Детская комната' %}
  • + {% endif %} + {% if place.disabled_service %} +
  • {% trans 'Сервис для инвалидов' %}
  • + {% endif %} +
+
    + {% if place.conference_centre %} +
  • {% trans 'Конгресс-центр' %}
  • + {% endif %} + {% if place.business_centre %} +
  • {% trans 'Бизнес-центр' %}
  • + {% endif %} + {% if place.online_registration %} +
  • {% trans 'Онлайн-регистрация' %}
  • + {% endif %} + {% if place.cafe %} +
  • {% trans 'Кафе и рестораны' %}
  • + {% endif %} +
+
    + {% if place.terminals %} +
  • {% trans 'Информационные терминалы' %}
  • + {% endif %} + {% if place.parking %} +
  • {% trans 'Парковка' %}
  • + {% endif %} + {% if place.press_centre %} +
  • {% trans 'Пресс-центр' %}
  • + {% endif %} + {% if place.mobile_application %} +
  • {% trans 'Мобильное приложение' %}
  • + {% endif %} +
+ {% else %} +
    + {% if place.exposition_hall %} +
  • {% trans 'Выставочный зал' %}
  • + {% endif %} + {% if place.wifi %} +
  • Wi-Fi
  • + {% endif %} + {% if place.multimedia_equipment %} +
  • {% trans 'Мультимедийное оборудование' %}
  • + {% endif %} + {% if place.conference_call %} +
  • {% trans 'Конференц-связь' %}
  • + {% endif %} +
+
    + {% if place.translate_equipment %} +
  • {% trans 'Оборудование для синхронного перевода' %}
  • + {% endif %} + {% if place.banquet_hall %} +
  • {% trans 'Банкетный зал' %}
  • + {% endif %} + {% if place.catering %} +
  • {% trans 'Кейтеринг' %}
  • + {% endif %} + {% if place.hotel %} +
  • {% trans 'Гостиница' %}
  • + {% endif %} +
+ {% endif %} +
+
\ No newline at end of file