remotes/origin/1203
kotzilla 11 years ago
parent befbbd4459
commit 21271c5132
  1. 69
      accounts/admin.py
  2. 6
      accounts/admin_urls.py
  3. 2
      accounts/edit_forms.py
  4. 83
      accounts/forms.py
  5. 137
      accounts/models.py
  6. 1
      accounts/signals.py
  7. 13
      accounts/urls.py
  8. 244
      accounts/views.py
  9. 11
      city/forms.py
  10. 8
      city/models.py
  11. 48
      company/admin.py
  12. 15
      company/admin_urls.py
  13. 4
      company/edit_forms.py
  14. 16
      company/models.py
  15. 52
      company/search_indexes.py
  16. 1
      company/views.py
  17. 3
      conference/models.py
  18. 3
      core/views.py
  19. 9
      country/admin.py
  20. 8
      country/models.py
  21. 51
      exposition/admin.py
  22. 12
      exposition/admin_urls.py
  23. 158
      exposition/forms.py
  24. 5
      exposition/management/commands/convert_expo_logo.py
  25. 435
      exposition/management/commands/exposition_load.py
  26. 5
      exposition/manager.py
  27. 75
      exposition/models.py
  28. 47
      exposition/search_indexes.py
  29. 88
      exposition/urls.py
  30. 511
      exposition/views.py
  31. 67
      file/forms.py
  32. 13
      functions/admin_forms.py
  33. 14
      functions/admin_views.py
  34. 48
      functions/custom_views.py
  35. 5
      functions/form_check.py
  36. 16
      functions/model_mixin.py
  37. 371
      functions/search_forms.py
  38. 65
      functions/search_mixin.py
  39. 10
      import_xls/admin.py
  40. 199
      import_xls/excel_settings.py
  41. 46
      import_xls/import_forms.py
  42. 22
      import_xls/model_utils.py
  43. 172
      import_xls/utils.py
  44. BIN
      media/imgs/149.jpeg
  45. BIN
      media/imgs/27159.gif
  46. BIN
      media/imgs/ALUMINIUM 2012.jpg
  47. BIN
      media/imgs/AMB 2012.jpg
  48. BIN
      media/imgs/Automechanika 2012.jpeg
  49. BIN
      media/imgs/Bio-Europe.jpg
  50. BIN
      media/imgs/BioNord 2014.jpg
  51. BIN
      media/imgs/BioSud 2014.jpg
  52. BIN
      media/imgs/CBB-China Brew & China Beverage.jpg
  53. BIN
      media/imgs/CEF Summer Chengdu 2014.jpeg
  54. BIN
      media/imgs/CIMES china.jpg
  55. BIN
      media/imgs/CWIEME Berlin.jpeg
  56. BIN
      media/imgs/CWMEE China expo.jpg
  57. BIN
      media/imgs/Cersaie_logo.jpg
  58. BIN
      media/imgs/Cosmetic_Business.jpg
  59. BIN
      media/imgs/Eltec Nurnberg 2013 .gif
  60. BIN
      media/imgs/EuroBLECH 2012.jpg
  61. BIN
      media/imgs/FILExpo China.gif
  62. BIN
      media/imgs/Fachdental Leipzig 2012.jpg
  63. BIN
      media/imgs/Filtration and Separation Asia 2014.jpg
  64. BIN
      media/imgs/Flomart.jpg
  65. BIN
      media/imgs/FlowEx China 2014.jpeg
  66. BIN
      media/imgs/Furniture China.jpg
  67. BIN
      media/imgs/Guangzhou International Lighting Exhibition 2012.jpeg
  68. BIN
      media/imgs/HOGA.png
  69. BIN
      media/imgs/Logo_Aquatech_China_NEG.jpg
  70. BIN
      media/imgs/about-j-13151-1.gif
  71. BIN
      media/imgs/agrar-unternehmertage-9863-1.jpg
  72. BIN
      media/imgs/agrochemex-13588-1.gif
  73. BIN
      media/imgs/airtec-10923-1.jpg
  74. BIN
      media/imgs/all-china-shoetch-9997-1.gif
  75. BIN
      media/imgs/all_in_print_logo_842.jpg
  76. BIN
      media/imgs/aluminium-china-6392-1.gif
  77. BIN
      media/imgs/ambiente-lavoro-2913-1.gif
  78. BIN
      media/imgs/analytica-china-3387-1.gif
  79. BIN
      media/imgs/animal-105-1.gif
  80. BIN
      media/imgs/arbeitsschutz-aktuell-9855-1.gif
  81. BIN
      media/imgs/asia-bike-16381-1.gif
  82. BIN
      media/imgs/asia-outdoor-trade-fair-14181-1.gif
  83. BIN
      media/imgs/asiamold-15926-1.gif
  84. BIN
      media/imgs/asme-turbo-expo-155-1.gif
  85. BIN
      media/imgs/auto-chongqing-14014-1.gif
  86. BIN
      media/imgs/auto-e-moto-d-epoca-11715-1.gif
  87. BIN
      media/imgs/auto-guangzhou-7498-1.gif
  88. BIN
      media/imgs/autochtona-9960-1.gif
  89. BIN
      media/imgs/automechanika-shanghai-4160-1.gif
  90. BIN
      media/imgs/automotive-testing-expo-china-7978-1.gif
  91. BIN
      media/imgs/automotive-testing-expo-europe-2681-1.gif
  92. BIN
      media/imgs/azubi-studientage-chemnitz-9872-1.1.gif
  93. BIN
      media/imgs/azubi-studientage-chemnitz-9872-1.2.gif
  94. BIN
      media/imgs/azubi-studientage-chemnitz-9872-1.3.gif
  95. BIN
      media/imgs/azubi-studientage-chemnitz-9872-1.gif
  96. BIN
      media/imgs/azubi-studientage-leipzig-12049-1.gif
  97. BIN
      media/imgs/babywelt-munchen-10255-1.gif
  98. BIN
      media/imgs/babywelt-stuttgart-10256-1.1.gif
  99. BIN
      media/imgs/babywelt-stuttgart-10256-1.gif
  100. BIN
      media/imgs/bau-253-1.gif
  101. Some files were not shown because too many files have changed in this diff Show More

@ -1,29 +1,25 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import random
import json
from hashlib import md5
from django.shortcuts import render_to_response from django.shortcuts import render_to_response
from django.conf import settings
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.template import RequestContext
from django.core.context_processors import csrf from django.core.context_processors import csrf
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
import random
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
#models and forms #models and forms
from models import User from models import User
from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm, UserFilterForm
#custom views #custom views
from functions.custom_views import objects_list from functions.admin_views import AdminView, AdminListView
from hashlib import md5
import json
class UserListView(AdminListView):
template_name = 'admin/accounts/user_list.html'
form_class = UserFilterForm
model = User
def user_all(request):
"""
Return list of all users with pagination
"""
return objects_list(request, User, 'user_all.html')
def user_change(request, url): def user_change(request, url):
""" """
Return form of user and post it on the server. Return form of user and post it on the server.
@ -38,12 +34,30 @@ def user_change(request, url):
return HttpResponseRedirect('/admin/accounts/all') return HttpResponseRedirect('/admin/accounts/all')
if request.POST: if request.POST:
# bug with saving staff users(set is_staff to False)
staff = user.is_staff
form = UserForm(request.POST, instance=user) form = UserForm(request.POST, instance=user)
if form.is_valid(): if form.is_valid():
form.save()
user = form.save()
if staff:
#
user.is_staff = True
user.save()
return HttpResponseRedirect('/admin/accounts/all') return HttpResponseRedirect('/admin/accounts/all')
else:
form.fields['city'].widget.attrs['data-init-text'] = user.profile.city.name
else: else:
form = UserForm(instance=user) profile = user.profile
data = {'country':profile.country_id, 'city': profile.city_id,
'title': profile.title, 'descriptions': profile.descriptions,
'keywords': profile.keywords, 'phone': profile.phone, 'web_page': profile.web_page,
'about': profile.about}
form = UserForm(instance=user,initial=data)
if user.profile.city: if user.profile.city:
form.fields['city'].widget.attrs['data-init-text'] = user.profile.city.name form.fields['city'].widget.attrs['data-init-text'] = user.profile.city.name
@ -51,6 +65,7 @@ def user_change(request, url):
args.update(csrf(request)) args.update(csrf(request))
args['form'] = form args['form'] = form
args['object'] = user
return render_to_response('user_change.html', args) return render_to_response('user_change.html', args)
@ -95,26 +110,6 @@ def create_md5(request):
return render_to_response('create_admin.html', args) return render_to_response('create_admin.html', args)
from django.core.mail import EmailMessage
def registration(request):
if request.POST:
form = UserCreationForm(request.POST)
if form.is_valid():
user = form.save()
email = EmailMessage('Subject', 'Body', to=['%s'%user.email])
email.send()
return HttpResponseRedirect('/admin/accounts/registration')
else:
form = UserCreationForm()
args = {}
args.update(csrf(request))
args['form'] = form
return render_to_response('registration.html', args)
def generatePassword(): def generatePassword():
""" """
@ -131,7 +126,7 @@ def generatePassword():
newPassword.append(SYMBOLS[random.randrange(0, len(SYMBOLS))]) newPassword.append(SYMBOLS[random.randrange(0, len(SYMBOLS))])
return ''.join(newPassword) return ''.join(newPassword)
from django.conf import settings
def reset_password_email(request): def reset_password_email(request):
""" """

@ -1,12 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from admin import UserListView
urlpatterns = patterns('', urlpatterns = patterns('',
#url(r'^registration/$', 'accounts.admin.registration'), #url(r'^registration/$', 'accounts.admin.registration'),
#url(r'^create_admin/$', 'accounts.admin.create_admin'), #url(r'^create_admin/$', 'accounts.admin.create_admin'),
#url(r'^create_md5user/$', 'accounts.admin.create_md5'), #url(r'^create_md5user/$', 'accounts.admin.create_md5'),
url(r'^change/(.*)/$', 'accounts.admin.user_change'), url(r'^change/(.*)/$', 'accounts.admin.user_change'),
# url(r'^change/(?P<user_id>\d+).*/$', 'accounts.views.user_change'), url(r'^all/$', UserListView.as_view()),
url(r'^all/$', 'accounts.admin.user_all'),
url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'), url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'),
) )

@ -59,7 +59,7 @@ class HomeForm(forms.ModelForm):
class WorkForm(forms.ModelForm): class WorkForm(forms.ModelForm):
position = forms.CharField(label=_(u'Укажите вашу должность'), position = forms.CharField(label=_(u'Укажите вашу должность'),
required=False, widget=forms.TextInput(attrs={'style': 'height: 42px;'})) required=False, widget=forms.TextInput())
company = forms.CharField(label=_(u'Место работы'), widget=forms.HiddenInput(attrs={'class': 'select2'})) company = forms.CharField(label=_(u'Место работы'), widget=forms.HiddenInput(attrs={'class': 'select2'}))
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

@ -11,6 +11,18 @@ from organiser.models import Organiser
#functions #functions
from functions.form_check import translit_with_separator, is_latin from functions.form_check import translit_with_separator, is_latin
def clean_relation_field(inst, field_name, model):
id = inst.cleaned_data[field_name]
if id:
try:
return model.objects.get(id=id)
except model.DoesNotExist:
return None
return None
class UserCreationForm(forms.ModelForm): class UserCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Пароль', widget=forms.PasswordInput(render_value=False)) password1 = forms.CharField(label='Пароль', widget=forms.PasswordInput(render_value=False))
password2 = forms.CharField(label='Повторите пароль', widget=forms.PasswordInput(render_value=False)) password2 = forms.CharField(label='Повторите пароль', widget=forms.PasswordInput(render_value=False))
@ -19,6 +31,7 @@ class UserCreationForm(forms.ModelForm):
model = User model = User
fields = ('email', 'first_name', 'last_name') fields = ('email', 'first_name', 'last_name')
def clean_email(self): def clean_email(self):
""" """
checking if user already exist checking if user already exist
@ -57,22 +70,46 @@ class UserChangeForm(forms.ModelForm):
def clean_password(self): def clean_password(self):
return self.initial['password'] return self.initial['password']
class UserForm(forms.ModelForm): class UserForm(forms.ModelForm):
email = forms.EmailField(widget=forms.TextInput(attrs={'disabled' : True}), required=False) #email = forms.EmailField(widget=forms.TextInput(attrs={'disabled' : True}), required=False)
country = forms.ModelChoiceField(label='Страна', queryset=Country.objects.all(), empty_label=None, required=False) country = forms.ChoiceField(label='Страна', choices=[(item.id, item.name) for item in Country.objects.all()], required=False)
city = forms.CharField(label='Город', widget=forms.HiddenInput()) city = forms.CharField(label='Город', widget=forms.HiddenInput())
company = forms.ModelChoiceField(label='Компания', queryset=Company.objects.all(), empty_label='', required=False) company = forms.ChoiceField(label='Компания', choices=[(item.id, item.name) for item in Company.objects.language().all()], required=False)
organiser = forms.ModelChoiceField(label='Организатор', queryset=Organiser.objects.all(), empty_label='', required=False) organiser = forms.ChoiceField(label='Организатор', choices=[(item.id, item.name) for item in Organiser.objects.language().all()], required=False)
title = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False) title = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False)
descriptions = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False) descriptions = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False)
keywords = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False) keywords = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False)
phone = forms.CharField(widget=forms.TextInput(attrs={'style':'width: 550px'}), required=False)
web_page = forms.URLField(required=False)
about = forms.CharField(widget=forms.Textarea())
class Meta: class Meta:
model = User model = User
exclude = ('last_login', 'password', 'is_active', 'is_admin', 'is_superuser', 'is_staff' exclude = ('username', 'email','last_login', 'password', 'is_active', 'is_admin', 'is_superuser', 'is_staff'
'date_joined', 'date_registered', 'date_modified') 'date_joined', 'date_registered', 'date_modified')
def save(self, force_insert=False, force_update=False, commit=True):
user = super(UserForm, self).save(commit=False)
data = self.cleaned_data
profile = user.profile
profile.country = data.get('country')
profile.city = data.get('city')
profile.title = data.get('title', '')
profile.descriptions = data.get('descriptions', '')
profile.keywords = data.get('keywords', '')
profile.phone = data.get('phone')
profile.web_page = data.get('web_page')
profile.about = data.get('about')
if commit:
user.save()
profile.save()
return user
"""
def clean_url(self): def clean_url(self):
url = self.cleaned_data.get('url') url = self.cleaned_data.get('url')
try: try:
@ -82,6 +119,21 @@ class UserForm(forms.ModelForm):
except: except:
return url return url
raise forms.ValidationError('Такой урл уже занят') raise forms.ValidationError('Такой урл уже занят')
"""
def clean_organiser(self):
return clean_relation_field(self, 'organiser', Organiser)
def clean_company(self):
return clean_relation_field(self, 'company', Company)
def clean_country(self):
return clean_relation_field(self, 'country', Country)
def clean_city(self):
return clean_relation_field(self, 'city', City)
def clean_phone(self): def clean_phone(self):
""" """
@ -99,7 +151,7 @@ class UserForm(forms.ModelForm):
return phone return phone
else: else:
raise forms.ValidationError('Введите правильный код страны') raise forms.ValidationError('Введите правильный код страны')
"""
def clean_web_page(self): def clean_web_page(self):
cleaned_data = super(UserForm, self).clean() cleaned_data = super(UserForm, self).clean()
web_page = cleaned_data.get('web_page') web_page = cleaned_data.get('web_page')
@ -112,6 +164,7 @@ class UserForm(forms.ModelForm):
return web_page return web_page
except: except:
return forms.ValidationError('Введите правильный адрес страници') return forms.ValidationError('Введите правильный адрес страници')
"""
class ChangePasswordForm(forms.Form): class ChangePasswordForm(forms.Form):
""" """
@ -232,3 +285,21 @@ class RecoveryForm(forms.Form):
class UserFilterForm(forms.Form):
model = User
email = forms.CharField(label=_(u'Email'), required=False)
def filter(self):
"""
return filtered queryset
form must be cleaned before calling this method
"""
data = self.cleaned_data
email = data['email']
model = self.model
qs = model.objects.all()
if email:
qs = qs.filter(email__contains=email)
return qs

@ -1,16 +1,18 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import random, string
from django.db import models from django.db import models
from hvad.models import TranslatableModel, TranslatedFields from django.core.validators import email_re
from django.db.models import Q
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
from django.core.mail import send_mail from django.core.mail import send_mail
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.db.models.signals import post_save from django.db.models.signals import post_save
from django.db.models.loading import get_model
#custom functions #custom functions
from functions.form_check import translit_with_separator from functions.form_check import translit_with_separator
import random, string
from django.core.validators import email_re
from django.db.models import Q
""" """
from django.contrib.auth.hashers import check_password from django.contrib.auth.hashers import check_password
@ -96,9 +98,14 @@ class User(AbstractBaseUser, PermissionsMixin):
Implementing a fully featured User model with Implementing a fully featured User model with
admin-compliant permissions. admin-compliant permissions.
stored main data about users
Email, first name, last name and password are required. Other fields are optional. Email, first name, last name and password are required. Other fields are optional.
""" """
catalog = '/user/'
email = models.EmailField( email = models.EmailField(
verbose_name = u'Email', verbose_name = u'Email',
max_length = 255, max_length = 255,
@ -167,29 +174,60 @@ class User(AbstractBaseUser, PermissionsMixin):
return True return True
def get_expositions_number(self): def get_expositions_number(self):
return len(self.exposition_users.all()) # 1 query
return self.exposition_users.all().count()
def get_conferences_number(self): def get_conferences_number(self):
return len(self.conference_users.all()) # 1 query
return self.conference_users.all().count()
def get_seminars_number(self): def get_seminars_number(self):
return len(self.seminar_users.all()) # 1 query
return self.seminar_users.all().count()
def get_webinars_number(self): def get_webinars_number(self):
return len(self.webinar_users.all()) # 1 query
return self.webinar_users.all().count()
def get_events_number(self): def get_events_number(self):
# 4 query
n = self.get_expositions_number() + self.get_conferences_number() + self.get_seminars_number() + self.get_webinars_number() n = self.get_expositions_number() + self.get_conferences_number() + self.get_seminars_number() + self.get_webinars_number()
return n return n
def get_permanent_url(self): def get_permanent_url(self):
if self.url: if self.url:
return '/user/'+self.url+'/'
return '/user/'+str(self.id)+'/' return self.catalog+self.url+'/'
return self.catalog+str(self.id)+'/'
def get_expos(self):
"""
return information about expos and them related data by 1 query
"""
return self.exposition_users.language().select_related('country', 'city', 'place').all()
def get_confs(self):
"""
return information about confs and them related data by 1 query
"""
return self.conference_users.language().select_related('country', 'city', 'place').all()
def get_seminars(self):
"""
return information about seminars and them related data by 1 query
"""
return self.seminar_users.language().select_related('country', 'city').all()
class Profile(models.Model): class Profile(models.Model):
"""
stores additional information about users
"""
user = models.OneToOneField(User) user = models.OneToOneField(User)
country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True, country = models.ForeignKey('country.Country', verbose_name='Страна', blank=True, null=True,
on_delete=models.PROTECT, related_name='users') on_delete=models.PROTECT, related_name='users')
@ -213,19 +251,53 @@ class Profile(models.Model):
keywords = models.CharField(max_length=255, blank=True) keywords = models.CharField(max_length=255, blank=True)
from dateutil.relativedelta import relativedelta
class Calendar(models.Model): class Calendar(models.Model):
"""
Store information about events, which user can add to own calendar
every user has one calendar
"""
user = models.OneToOneField(User) user = models.OneToOneField(User)
expositions = models.ManyToManyField('exposition.Exposition', null=True) expositions = models.ManyToManyField('exposition.Exposition', null=True)
conferences = models.ManyToManyField('conference.Conference', null=True) conferences = models.ManyToManyField('conference.Conference', null=True)
seminars = models.ManyToManyField('seminar.Seminar', null=True) seminars = models.ManyToManyField('seminar.Seminar', null=True)
webinars = models.ManyToManyField('webinar.Webinar', null=True) webinars = models.ManyToManyField('webinar.Webinar', null=True)
def get_expos(self):
# 1 query
return list(self.expositions.language().all())
def get_confs(self):
# 1 query
return list(self.conferences.language().all())
def get_seminars(self):
# 1 query
return list(self.seminars.language().all())
def get_webinars(self):
# 1 query
return list(self.webinars.language().all())
def get_events(self): def get_events(self):
events = list(self.expositions.all()) + list(self.conferences.all()) + list(self.seminars.all()) + list(self.webinars.all()) # 4 query
events = self.get_expos() + self.get_confs() + self.get_seminars() + self.get_webinars()
return events return events
def check_in_calendar(self, event):
"""
check if event in calendar
1 query
"""
event_type = event.event_type
if event_type == 'expo':
return event in self.get_expos()
elif event_type == 'conf':
return event in self.get_confs()
elif event_type == 'seminar':
return event in self.get_seminars()
elif event_type == 'webinar':
return event in self.get_webinars()
def events_by_month(self, day): def events_by_month(self, day):
exp = list(self.expositions.filter((Q(data_begin__month=day.month) & Q(data_begin__year=day.year))\ exp = list(self.expositions.filter((Q(data_begin__month=day.month) & Q(data_begin__year=day.year))\
@ -240,12 +312,51 @@ class Calendar(models.Model):
return exp+con+sem+web return exp+con+sem+web
class EventFilter(models.Model):
user = models.OneToOneField(User)
theme = models.ManyToManyField('theme.Theme', null=True)
tag = models.ManyToManyField('theme.Tag', null=True)
area = models.ManyToManyField('country.Area', null=True)
country = models.ManyToManyField('country.Country', null=True)
city = models.ManyToManyField('city.City', null=True)
fr = models.DateField(blank=True, null=True)
to = models.DateField(blank=True, null=True)
def get_queryset(self):
Exposition = get_model('exposition', 'Exposition')
qs = Exposition.objects.all()
themes = self.theme.all()
tags = self.tag.all()
countries = self.country.all()
areas = self.area.all()
cities = self.city.all()
if themes.count():
qs = qs.filter(theme__in=list(themes))
if tags.count():
qs = qs.filter(tag__in=list(tags))
if cities.count():
qs = qs.filter(city__in=list(cities))
if areas.count():
qs = qs.filter(country__area__in=list(areas))
if countries.count():
qs = qs.filter(country__in=list(countries))
return qs.order_by('data_begin')
def create_user_inf(sender, instance, created, **kwargs): def create_user_inf(sender, instance, created, **kwargs):
if created: if created:
Calendar.objects.create(user=instance) Calendar.objects.create(user=instance)
Profile.objects.create(user=instance) Profile.objects.create(user=instance)
EventFilter.objects.create(user=instance)
post_save.connect(create_user_inf, sender=User) post_save.connect(create_user_inf, sender=User)

@ -2,8 +2,8 @@
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from views import SettingsView, ProfileView, CalendarView, UserView, UserExpositionsView, UserConferenceView, UserSeminarView from views import SettingsView, ProfileView, CalendarView, UserView, UserExpositionsView, UserConferenceView, UserSeminarView
from views import NameView, HomeView, AvatarView, WorkView, AboutCompanyView, PhoneView, EmailView, WebPageView,\ from views import NameView, HomeView, AvatarView, WorkView, AboutCompanyView, PhoneView, WebPageView,\
SocialView, AboutView, ProfileCompanyView SocialView, AboutView, ProfileCompanyView, Feed
# #
@ -16,6 +16,8 @@ urlpatterns = patterns('',
url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())), url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())),
url(r'^profile/settings/$', login_required(SettingsView.as_view())), url(r'^profile/settings/$', login_required(SettingsView.as_view())),
url(r'^profile/calendar/$', login_required(CalendarView.as_view())), url(r'^profile/calendar/$', login_required(CalendarView.as_view())),
url(r'^profile/feed/page/(?P<page>\d+)/$', Feed.as_view()),
url(r'^profile/feed/$', login_required(Feed.as_view())),
url(r'^user/(?P<url>.*)/expositions/(?P<page>\d+)/$', UserExpositionsView.as_view()), url(r'^user/(?P<url>.*)/expositions/(?P<page>\d+)/$', UserExpositionsView.as_view()),
url(r'^user/(?P<url>.*)/expositions/$', UserExpositionsView.as_view()), url(r'^user/(?P<url>.*)/expositions/$', UserExpositionsView.as_view()),
url(r'^user/(?P<url>.*)/seminars/(?P<page>\d+)/$', UserSeminarView.as_view()), url(r'^user/(?P<url>.*)/seminars/(?P<page>\d+)/$', UserSeminarView.as_view()),
@ -29,21 +31,16 @@ urlpatterns = patterns('',
#url(r'^profile/messages/(?P<user>.*)/$', login_required(MessagesView.as_view())), #url(r'^profile/messages/(?P<user>.*)/$', login_required(MessagesView.as_view())),
#url(r'^profile/messages/$', login_required(MessagesView.as_view())), #url(r'^profile/messages/$', login_required(MessagesView.as_view())),
# # ajax
url(r'^profile/update/name/$', login_required(NameView.as_view())), url(r'^profile/update/name/$', login_required(NameView.as_view())),
url(r'^profile/update/home/$', login_required(HomeView.as_view())), url(r'^profile/update/home/$', login_required(HomeView.as_view())),
url(r'^profile/update/avatar/$', login_required(AvatarView.as_view())), url(r'^profile/update/avatar/$', login_required(AvatarView.as_view())),
url(r'^profile/update/work/$', login_required(WorkView.as_view())), url(r'^profile/update/work/$', login_required(WorkView.as_view())),
url(r'^profile/update/about-company/$', login_required(AboutCompanyView.as_view())), url(r'^profile/update/about-company/$', login_required(AboutCompanyView.as_view())),
url(r'^profile/update/phone/$', login_required(PhoneView.as_view())), url(r'^profile/update/phone/$', login_required(PhoneView.as_view())),
url(r'^profile/update/email/$', login_required(EmailView.as_view())),
url(r'^profile/update/web-page/$', login_required(WebPageView.as_view())), url(r'^profile/update/web-page/$', login_required(WebPageView.as_view())),
url(r'^profile/update/social/$', login_required(SocialView.as_view())), url(r'^profile/update/social/$', login_required(SocialView.as_view())),
url(r'^profile/update/about/$', login_required(AboutView.as_view())), url(r'^profile/update/about/$', login_required(AboutView.as_view())),
url(r'^profile/change-password/', 'accounts.views.change_password'), url(r'^profile/change-password/', 'accounts.views.change_password'),
#
url(r'^accounts/get/calendar/(?P<year>\d+)/(?P<month>\d+)/$', 'accounts.views.get_calendar'),
url(r'^accounts/get-tag-users/$', 'accounts.views.user_for_tag'),
) )

@ -1,23 +1,28 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.shortcuts import render_to_response, get_object_or_404 import json, datetime
import calendar as python_calendar
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse, Http404 from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.utils.translation import ugettext as _, get_language from django.utils.translation import ugettext as _, get_language
from django.utils import timezone from django.utils import timezone
# forms from django_messages.forms import SendForm
from django.views.generic import TemplateView, FormView, ListView
from sorl.thumbnail import get_thumbnail
from forms import ChangePasswordForm, EmailAnnouncementForm from forms import ChangePasswordForm, EmailAnnouncementForm
from company.forms import CompanyFormClient, CreateCompanyForm from company.forms import CreateCompanyForm
from models import User
from edit_forms import AvatarForm, NameForm, HomeForm, WorkForm, AboutCompanyForm, PhoneForm, EmailForm,\ from edit_forms import AvatarForm, NameForm, HomeForm, WorkForm, AboutCompanyForm, PhoneForm, EmailForm,\
WebPageForm, SocialForm, AboutForm WebPageForm, SocialForm, AboutForm
from models import User
# python
import json, datetime
import calendar as python_calendar
from django.views.generic import TemplateView, FormView, ListView
from sorl.thumbnail import get_thumbnail
class SettingsView(TemplateView): class SettingsView(TemplateView):
"""
display template with user settings like:
password, email notifications, social settings, subscription
"""
template_name = 'accounts/settings.html' template_name = 'accounts/settings.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(SettingsView, self).get_context_data(**kwargs) context = super(SettingsView, self).get_context_data(**kwargs)
@ -26,69 +31,64 @@ class SettingsView(TemplateView):
return context return context
class CalendarView(TemplateView): class CalendarView(TemplateView):
"""
display template with user calendar(one month)
"""
template_name = 'accounts/calendar.html' template_name = 'accounts/calendar.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
"""
get events by 1 month and return to template
return additional variables:
- events - events in current months
- days - days in current month
- current_day
"""
context = super(CalendarView, self).get_context_data(**kwargs) context = super(CalendarView, self).get_context_data(**kwargs)
now = timezone.now().replace(microsecond=0, second=0, minute=0, hour=0) now = timezone.now().replace(microsecond=0, second=0, minute=0, hour=0)
context['current_day'] = now context['current_day'] = now
year = self.request.GET.get('year') year = self.request.GET.get('year')
month = self.request.GET.get('month') month = self.request.GET.get('month')
# cheack if its int
if year: if year:
year = int(year) year = int(year)
if month: if month:
month = int(month) month = int(month)
if not year or not month: if not year or not month:
# events in current months
number_of_days = python_calendar.monthrange(now.year, now.month)[1] number_of_days = python_calendar.monthrange(now.year, now.month)[1]
# number of days in current month
days = [timezone.make_aware(datetime.datetime(now.year, now.month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)] days = [timezone.make_aware(datetime.datetime(now.year, now.month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)]
context['days'] = days context['days'] = days
# --------------------
calendar = self.request.user.calendar calendar = self.request.user.calendar
# events in current month
context['events'] = calendar.events_by_month(now) context['events'] = calendar.events_by_month(now)
else: else:
number_of_days = python_calendar.monthrange(year, month)[1] number_of_days = python_calendar.monthrange(year, month)[1]
days = [timezone.make_aware(datetime.datetime(year, month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)] days = [timezone.make_aware(datetime.datetime(year, month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)]
# number of days in current month
context['days'] = days context['days'] = days
calendar = self.request.user.calendar calendar = self.request.user.calendar
now = now.replace(year=year, month=month, day=1) now = now.replace(year=year, month=month, day=1)
# events in current month
context['events'] = calendar.events_by_month(now) context['events'] = calendar.events_by_month(now)
return context return context
def events_handeler(obj):
response = {'name': obj.name, 'country': obj.country.name, 'city': obj.city.name}
if obj.place:
response['place'] = obj.place.name
return response
@login_required
def get_calendar(request, year, month):
now = timezone.now().replace(microsecond=0, second=0, minute=0, hour=0)
day = timezone.make_aware(datetime.datetime(year=int(year), month=int(month), day=1), timezone.get_default_timezone())
calendar = request.user.calendar
number_of_days = python_calendar.monthrange(day.year, day.month)[1]
days = [timezone.make_aware(datetime.datetime(day.year, day.month, i+1), timezone.get_default_timezone()) for i in range(number_of_days)]
args = {}
dthandler = lambda obj: (obj.isoformat() if isinstance(obj, datetime.datetime) or isinstance(obj, datetime.date) else None)
args['days'] = json.dumps(days, default=dthandler)
args['current_day'] = json.dumps(now, default=dthandler)
events = calendar.events_by_month(day)
args['events'] = json.dumps(events, default=events_handeler)
return HttpResponse(json.dumps(args), content_type='application/json')
class ProfileView(TemplateView): class ProfileView(TemplateView):
"""
display template with user information forms
in template forms handles dynamically by ajax
"""
template_name = 'accounts/new_profile.html' template_name = 'accounts/new_profile.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -116,6 +116,10 @@ from company.edit_forms import NameForm as CompNameForm, HomeForm as CompHomeFor
FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress FoundationForm as CompFound, SpecializationForm as CompSpec, AddressForm as CompAddress
class ProfileCompanyView(TemplateView): class ProfileCompanyView(TemplateView):
"""
display template with user company information forms
in template forms handles dynamically by ajax
"""
template_name = 'accounts/fill_company.html' template_name = 'accounts/fill_company.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -147,11 +151,12 @@ class ProfileCompanyView(TemplateView):
class MessagesView(TemplateView):
template_name = 'accounts/messages.html'
from django_messages.forms import SendForm
class UserView(TemplateView): class UserView(TemplateView):
"""
display user information for another users
"""
template_name = 'accounts/user.html' template_name = 'accounts/user.html'
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
@ -168,45 +173,9 @@ class UserView(TemplateView):
return context return context
@login_required
def change_password(request):
"""
Change current user password if new password is valid
"""
success = {'success': False}
if request.POST:
form = ChangePasswordForm(request.POST)
if form.is_valid():
user = request.user
if(user.check_password(form.cleaned_data.get('old_password'))):
user.set_password(form.cleaned_data.get('new_password'))
user.save()
success['success'] = True
success['message'] = _(u'Пароль изменен')
return HttpResponse(json.dumps(success), content_type='application/json')
else:
errors = {'errors': [_(u'Не правильный пароль')]}
success.update(errors)
return HttpResponse(json.dumps(success), content_type='application/json')
else:
errors = [err[0] for err in form.errors.values()]
errors = {'errors': errors}
success.update(errors)
return HttpResponse(json.dumps(success), content_type='application/json')
else:
return HttpResponse(json.dumps(success), content_type='application/json')
def user_for_tag(request):
users = [{'id': user.id, 'label': user.get_full_name(), 'value': user.get_full_name() } for user in User.objects.all()]
return HttpResponse(json.dumps(users), content_type='application/json')
class ProfileInvalidView(FormView): class ProfileInvalidView(FormView):
""" """
abstract view abstract view. handles form errors. return errors in json
""" """
def form_invalid(self, form): def form_invalid(self, form):
response = {'success': False} response = {'success': False}
@ -216,7 +185,8 @@ class ProfileInvalidView(FormView):
class BaseProfileView(ProfileInvalidView): class BaseProfileView(ProfileInvalidView):
""" """
abstract view abstract view for ajax calls. handles form with instance profile
return json
""" """
def form_valid(self, form): def form_valid(self, form):
profile = self.request.user.profile profile = self.request.user.profile
@ -226,73 +196,87 @@ class BaseProfileView(ProfileInvalidView):
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
class WorkView(ProfileInvalidView): class WorkView(ProfileInvalidView):
"""
instance user
"""
form_class = WorkForm form_class = WorkForm
def form_valid(self, form): def form_valid(self, form):
user = self.request.user user = self.request.user
form = self.form_class(self.request.POST, instance=user) form = self.form_class(self.request.POST, instance=user)
form.save() user = form.save()
response = {'success': True} company = user.company
response = {'success': True, 'url':company.get_permanent_url()}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
class AvatarView(BaseProfileView): class AvatarView(BaseProfileView):
"""
instance profile. save user avatar.
if call is ajax- return json data, else redirect to profile page
"""
form_class = AvatarForm form_class = AvatarForm
def form_valid(self, form): def form_valid(self, form):
profile = self.request.user.profile profile = self.request.user.profile
if not self.request.FILES:
response = {'success': False, 'message':'files is empty'}
return HttpResponse(json.dumps(response), content_type='application/json')
form = self.form_class(self.request.POST, self.request.FILES, instance=profile) form = self.form_class(self.request.POST, self.request.FILES, instance=profile)
form.save() form.save()
if self.request.is_ajax(): if self.request.is_ajax():
im = get_thumbnail(profile.avatar, '100x100', crop='center') im = get_thumbnail(profile.avatar, '100x100', crop='center')
response = {'success': True, 'url': im.url} response = {'success': True, 'url': im.url}
#response = {'success': True}
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
else: else:
return HttpResponseRedirect('/profile/') return HttpResponseRedirect('/profile/')
class HomeView(BaseProfileView): class HomeView(BaseProfileView):
"""
instance profile
"""
form_class = HomeForm form_class = HomeForm
class AboutCompanyView(BaseProfileView): class AboutCompanyView(BaseProfileView):
"""
instance profile
"""
form_class = AboutCompanyForm form_class = AboutCompanyForm
class PhoneView(BaseProfileView): class PhoneView(BaseProfileView):
"""
instance profile
"""
form_class = PhoneForm form_class = PhoneForm
class WebPageView(BaseProfileView): class WebPageView(BaseProfileView):
"""
instance profile
"""
form_class = WebPageForm form_class = WebPageForm
class SocialView(BaseProfileView): class SocialView(BaseProfileView):
"""
instance profile
"""
form_class = SocialForm form_class = SocialForm
class AboutView(BaseProfileView): class AboutView(BaseProfileView):
"""
instance profile
"""
form_class = AboutForm form_class = AboutForm
class EmailView(ProfileInvalidView):
form_class = EmailForm
def form_valid(self, form):
user = self.request.user
form = self.form_class(self.request.POST, instance=user)
#form.save()
response = {'success': False}
return HttpResponse(json.dumps(response), content_type='application/json')
class NameView(ProfileInvalidView): class NameView(ProfileInvalidView):
"""
instance user
"""
form_class = NameForm form_class = NameForm
def form_valid(self, form): def form_valid(self, form):
@ -303,10 +287,6 @@ class NameView(ProfileInvalidView):
return HttpResponse(json.dumps(response), content_type='application/json') return HttpResponse(json.dumps(response), content_type='application/json')
def test(request):
return HttpResponse('test')
from exposition.models import Exposition from exposition.models import Exposition
@ -321,7 +301,7 @@ def get_user(url):
class UserEventView(ListView): class UserEventView(ListView):
model = Exposition model = Exposition
template_name = 'accounts/user_events.html' template_name = 'accounts/user_events.html'
paginate_by = 2 paginate_by = 10
obj = None obj = None
event_type = None event_type = None
@ -330,7 +310,7 @@ class UserEventView(ListView):
url = self.kwargs.get('url') url = self.kwargs.get('url')
user = get_user(url) user = get_user(url)
self.obj = user self.obj = user
return user.exposition_users.all() return user.exposition_users.language().select_related('country').all()
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(UserEventView, self).get_context_data(**kwargs) context = super(UserEventView, self).get_context_data(**kwargs)
@ -339,28 +319,78 @@ class UserEventView(ListView):
return context return context
class UserExpositionsView(UserEventView): class UserExpositionsView(UserEventView):
"""
return template with list of expos that user joined
"""
event_type = _(u'Выставки') event_type = _(u'Выставки')
def get_queryset(self): def get_queryset(self):
url = self.kwargs.get('url') url = self.kwargs.get('url')
user = get_user(url) user = get_user(url)
self.obj = user self.obj = user
return user.exposition_users.all() return user.get_expos()
class UserConferenceView(UserEventView): class UserConferenceView(UserEventView):
"""
return template with list of confs that user joined
"""
event_type = _(u'Конференции') event_type = _(u'Конференции')
def get_queryset(self): def get_queryset(self):
url = self.kwargs.get('url') url = self.kwargs.get('url')
user = get_user(url) user = get_user(url)
self.obj = user self.obj = user
return user.conference_users.all() return user.get_confs()
class UserSeminarView(UserEventView): class UserSeminarView(UserEventView):
"""
return template with list of seminars that user joined
"""
event_type = _(u'Семинары') event_type = _(u'Семинары')
def get_queryset(self): def get_queryset(self):
url = self.kwargs.get('url') url = self.kwargs.get('url')
user = get_user(url) user = get_user(url)
self.obj = user self.obj = user
return user.seminar_users.all() return user.get_seminars()
@login_required
def change_password(request):
"""
Change current user password if new password is valid
"""
success = {'success': False}
if request.POST:
form = ChangePasswordForm(request.POST)
if form.is_valid():
user = request.user
if(user.check_password(form.cleaned_data.get('old_password'))):
user.set_password(form.cleaned_data.get('new_password'))
user.save()
success['success'] = True
success['message'] = _(u'Пароль изменен')
return HttpResponse(json.dumps(success), content_type='application/json')
else:
errors = {'errors': [_(u'Не правильный пароль')]}
success.update(errors)
return HttpResponse(json.dumps(success), content_type='application/json')
else:
errors = [err[0] for err in form.errors.values()]
errors = {'errors': errors}
success.update(errors)
return HttpResponse(json.dumps(success), content_type='application/json')
else:
return HttpResponse(json.dumps(success), content_type='application/json')
class Feed(ListView):
template_name = 'client/accounts/feed.html'
paginate_by = 5
model = Exposition
def get_queryset(self):
filter = self.request.user.eventfilter
qs = filter.get_queryset()
return qs

@ -94,10 +94,10 @@ class CityForm(forms.Form):
#city.country = Country.objects.get(id=data['country'].id)# .id cause select uses queryset #city.country = Country.objects.get(id=data['country'].id)# .id cause select uses queryset
# url generate for city: "country_name-city_name" # url generate for city: "country_name-city_name"
if data.get('name_en'): #if data.get('name_en'):
city.url = '%s-'%translit_with_separator(city.country.name) + translit_with_separator(data['name_en']).lower() #city.url = '%s-'%translit_with_separator(city.country.name) + translit_with_separator(data['name_en']).lower()
else: #else:
city.url = '%s-'%translit_with_separator(city.country.name) + translit_with_separator(data['name_ru']).lower() #city.url = '%s-'%translit_with_separator(city.country.name) + translit_with_separator(data['name_ru']).lower()
#city.url = '%s'%translit_with_separator(data['name_ru'].strip()).lower() #city.url = '%s'%translit_with_separator(data['name_ru'].strip()).lower()
#city.save() #city.save()
@ -114,7 +114,7 @@ class CityForm(forms.Form):
name_ru = self.cleaned_data.get('name_ru') name_ru = self.cleaned_data.get('name_ru')
name_en = self.cleaned_data.get('name_en') name_en = self.cleaned_data.get('name_en')
country = self.cleaned_data.get('country') country = self.cleaned_data.get('country')
"""
city = City.objects.filter( city = City.objects.filter(
url='%s-%s'%(translit_with_separator(country.name), translit_with_separator(name_en)) url='%s-%s'%(translit_with_separator(country.name), translit_with_separator(name_en))
) )
@ -126,6 +126,7 @@ class CityForm(forms.Form):
msg = 'Город с таким названием уже существует' msg = 'Город с таким названием уже существует'
self._errors['name_ru'] = ErrorList([msg]) self._errors['name_ru'] = ErrorList([msg])
del self.cleaned_data['name_ru'] del self.cleaned_data['name_ru']
"""
return self.cleaned_data return self.cleaned_data

@ -85,6 +85,14 @@ class City(TranslatableModel):
return len(Exposition.objects.filter(city=self.id)) return len(Exposition.objects.filter(city=self.id))
def get_parent(self):
parent = {'text' : self.country.name, 'id': self.country.id, 'name': 'co',
'parent':{'text' : self.country.area.name, 'id': self.country.area.id, 'name': 'area'}}
return parent
def get_sub_categories(self):
return []

@ -14,7 +14,7 @@ from file.models import FileModel, TmpFile
from file.forms import FileModelForm from file.forms import FileModelForm
#custom views #custom views
from functions.custom_views import objects_list, add_object_with_file, delete_object from functions.custom_views import objects_list, add_object_with_file, delete_object
from functions.admin_views import AdminListView from functions.admin_views import AdminListView, AdminView
def company_all(request): def company_all(request):
@ -67,7 +67,7 @@ def company_change(request, url):
#fill form with data from database #fill form with data from database
data = {'url':company.url, 'staff_number':company.staff_number, 'address': company.address, data = {'url':company.url, 'staff_number':company.staff_number, 'address': company.address,
'phone':company.phone, 'fax':company.fax, 'web_page':company.web_page, 'phone':company.phone, 'fax':company.fax, 'web_page':company.web_page,
'email':company.email, 'social':company.social, 'foundation': company.foundation, 'email':company.email, 'foundation': company.foundation,
'company_id':company.id} 'company_id':company.id}
if company.country: if company.country:
@ -113,3 +113,47 @@ class CompanyListView(AdminListView):
template_name = 'admin/company/company_list.html' template_name = 'admin/company/company_list.html'
form_class = CompanyFilterForm form_class = CompanyFilterForm
model = Company model = Company
class CompanyView(AdminView):
form_class = CompanyForm
model = Company
template_name = 'admin/company/company.html'
success_url = '/admin/company/all/'
def get_form(self, form_class):
if self.request.POST:
return super(CompanyView, self).get_form(form_class)
obj = self.set_obj()
if obj:
data = {'url':obj.url, 'staff_number':obj.staff_number, 'address': obj.address,
'phone':obj.phone, 'fax':obj.fax, 'web_page':obj.web_page,
'email':obj.email, 'foundation': obj.foundation,
'company_id':obj.id}
if obj.country:
data['country'] = obj.country_id
if obj.city:
data['city'] = obj.city_id
data['theme'] = [item.id for item in obj.theme.all()]
data['tag'] = ','.join(['%s:%s'%(item.id, item.name) for item in obj.tag.all()])
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] = trans_obj.name
data['description_%s' % code] = trans_obj.description
data['specialization_%s' % code] = trans_obj.specialization
data['address_inf_%s' % code] = trans_obj.address_inf
data['representation_%s' % code] = trans_obj.representation
data['title_%s' % code] = trans_obj.title
data['keywords_%s' % code] = trans_obj.keywords
data['descriptions_%s' % code] = trans_obj.descriptions
form =form_class(initial=data)
form.fields['city'].widget.attrs['data-init-text'] = obj.city.name
form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.filter(theme__in=data['theme'])]
return form
else:
return form_class()

@ -1,11 +1,16 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from admin import CompanyListView from admin import CompanyListView, CompanyView
urlpatterns = patterns('company.admin', urlpatterns = patterns('company.admin',
url(r'^add.*/$', 'company_add'),
url(r'^delete/(?P<url>.*)/$', 'company_delete'),
url(r'^change/(?P<url>.*).*/$', 'company_change'),
#url(r'^all/$', 'company_all'),
url(r'^all/$', CompanyListView.as_view()), url(r'^all/$', CompanyListView.as_view()),
url(r'^$', CompanyView.as_view()),
url(r'^(?P<url>.*)/$', CompanyView.as_view()),
#url(r'^add.*/$', 'company_add'),
#url(r'^delete/(?P<url>.*)/$', 'company_delete'),
#url(r'^change/(?P<url>.*).*/$', 'company_change'),
#url(r'^all/$', 'company_all'),
#url(r'^all/$', CompanyListView.as_view()),
) )

@ -19,7 +19,7 @@ class NameForm(BaseForm):
class SpecializationForm(BaseForm): class SpecializationForm(BaseForm):
translation = True translation = True
specialization = forms.CharField(label=_(u'Описание компании'), widget=forms.TextInput(attrs={'style': 'width: 420px;'})) specialization = forms.CharField(label=_(u'Описание компании'), widget=forms.TextInput())
class Meta: class Meta:
model = Company._meta.translations_model model = Company._meta.translations_model
fields = ('specialization',) fields = ('specialization',)
@ -114,7 +114,7 @@ class DescriptionForm(BaseForm):
class AddressForm(BaseForm): class AddressForm(BaseForm):
translation = True translation = True
address_inf = forms.CharField(label=_(u'Адрес компании'), widget=forms.TextInput(attrs={'style': 'width: 420px;'})) address_inf = forms.CharField(label=_(u'Адрес компании'), widget=forms.TextInput())
class Meta: class Meta:
model = Company._meta.translations_model model = Company._meta.translations_model
fields = ('address_inf',) fields = ('address_inf',)

@ -2,7 +2,7 @@
from django.db import models from django.db import models
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
# from django.utils import translation
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from functions.custom_fields import LocationField from functions.custom_fields import LocationField
from functions.models_methods import ExpoManager from functions.models_methods import ExpoManager
@ -16,6 +16,9 @@ class Company(TranslatableModel, ExpoMixin):
Uses hvad.TranslatableModel which is child of django.db.models class Uses hvad.TranslatableModel which is child of django.db.models class
""" """
catalog = '/members/'
catalog_name = _(u'Участники:')
search_name = None
objects = ExpoManager() objects = ExpoManager()
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id') files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
@ -62,11 +65,20 @@ class Company(TranslatableModel, ExpoMixin):
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', self.pk) return self.lazy_translation_getter('name', self.pk)
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
specializations = ' '.join([tr.specialization for tr in translations])
themes = ' '.join([' '.join(theme.get_all_names()) for theme in self.theme.all()])
tags = ' '.join([' '.join(tag.get_all_names()) for tag in self.tag.all()])
return names + ' ' + specializations + ' ' + themes + ' ' + tags
def get_catalog_url(self): def get_catalog_url(self):
return '/members/' return '/members/'
def get_permanent_url(self): def get_permanent_url(self):
url = '%smember-%s'%(self.get_catalog_url(), self.url) url = '%smember-%s'%(self.catalog, self.url)
return url return url
def get_expositions_number(self): def get_expositions_number(self):

@ -1,40 +1,34 @@
# -*- coding: utf-8 -*-
from haystack import indexes from haystack import indexes
from models import Company from models import Company
""" from functions.search_mixin import ExpoSearchMixin
class CompanyIndex(indexes.SearchIndex, indexes.Indexable):
class CompanyExpositionIndex(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()
content_auto = indexes.EdgeNgramField()
area_id = indexes.IntegerField()
country_id = indexes.IntegerField()
city_id = indexes.IntegerField()
theme = indexes.MultiValueField() theme = indexes.MultiValueField()
tag = indexes.MultiValueField() tag = indexes.MultiValueField()
country = indexes.CharField(model_attr='country', null=True) url = indexes.CharField()
city = indexes.CharField(model_attr='city', null=True) form_name = indexes.CharField()
# translated fields
def prepare_country(self, obj): name_en = indexes.CharField()
if obj.country: name_ru = indexes.CharField()
return '%s'%obj.country.id catalog_name_en = indexes.CharField()
return '' catalog_name_ru = indexes.CharField()
def prepare_city(self, obj):
if obj.city:
return '%s'%obj.city.id
return ''
def prepare_theme(self, obj): def prepare_form_name(self, obj):
return None
return [str(th.id) for th in obj.theme.filter()] def prepare_catalog_name_en(self, obj):
return u'Members'
def prepare_tag(self, obj): def prepare_catalog_name_ru(self, obj):
return [str(tag.id) for tag in obj.tag.filter()] return u'Участники'
def prepare_where(self, obj):
country = []
city = []
if obj.country:
country = [tr.name for tr in obj.country.translations.all()]
if obj.city:
city = [tr.name for tr in obj.city.translations.all()]
return country + city
def get_model(self): def get_model(self):
return Company return Company
@ -42,5 +36,3 @@ class CompanyIndex(indexes.SearchIndex, indexes.Indexable):
def index_queryset(self, using=None): def index_queryset(self, using=None):
return self.get_model().objects.filter() return self.get_model().objects.filter()
"""

@ -49,7 +49,6 @@ class CompanyView(ExpoListView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(CompanyView, self).get_context_data(**kwargs) context = super(CompanyView, self).get_context_data(**kwargs)
context['search_action'] = '/members/search/'
context['type'] = 'members search' context['type'] = 'members search'
return context return context

@ -24,6 +24,9 @@ class Conference(TranslatableModel, EventMixin, ExpoMixin):
Uses hvad.TranslatableModel which is child of django.db.models class Uses hvad.TranslatableModel which is child of django.db.models class
""" """
catalog = '/conference/'
# type of event
event_type = 'conf'
#set manager of this model #set manager of this model
objects = ExpoManager() objects = ExpoManager()

@ -9,7 +9,8 @@ from functions.views_help import split_params
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from forms import PlaceSearchForm #from forms import PlaceSearchForm
from functions.search_forms import PlaceSearchForm
from functions.search_forms import EventSearchForm from functions.search_forms import EventSearchForm
from haystack.query import EmptySearchQuerySet from haystack.query import EmptySearchQuerySet

@ -11,6 +11,7 @@ from file.models import FileModel
from file.forms import FileModelForm from file.forms import FileModelForm
#custom views #custom views
from functions.custom_views import objects_list, add_object_with_file, delete_object, filtered_list from functions.custom_views import objects_list, add_object_with_file, delete_object, filtered_list
from functions.admin_views import paginate_results
from functions.forms import AdminSearchForm from functions.forms import AdminSearchForm
from functions.admin_views import AdminListView from functions.admin_views import AdminListView
@ -111,7 +112,15 @@ def country_change(request, url):
return render_to_response('country_add.html', args) return render_to_response('country_add.html', args)
class CountryListView(AdminListView): class CountryListView(AdminListView):
template_name = 'admin/country/country_list.html' template_name = 'admin/country/country_list.html'
form_class = CountryFilterForm form_class = CountryFilterForm
model = Country model = Country
def get_context_data(self, **kwargs):
context = super(AdminListView, self).get_context_data(**kwargs)
qs = self.model.objects.all()
result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result
return context

@ -72,6 +72,10 @@ class Area(TranslatableModel):
objects = [{'text':item.name, 'id':item.id, 'name':'co', 'sub':True} for item in self.countries()] objects = [{'text':item.name, 'id':item.id, 'name':'co', 'sub':True} for item in self.countries()]
return objects return objects
def get_parent(self):
parent = {}
return parent
@ -165,6 +169,10 @@ class Country(TranslatableModel):
objects = [{'text':item.name, 'id':item.id, 'name':'ci', 'sub': False} for item in self.active_cities()] objects = [{'text':item.name, 'id':item.id, 'name':'ci', 'sub': False} for item in self.active_cities()]
return objects return objects
def get_parent(self):
parent = {'text' : self.area.name, 'id': self.area.id, 'name': 'area'}
return parent
post_save.connect(post_save_handler, sender=Country) post_save.connect(post_save_handler, sender=Country)

@ -13,7 +13,7 @@ from forms import ExpositionCreateForm, ExpositionDeleteForm, TimeTableForm, Sta
from theme.models import Tag from theme.models import Tag
from city.models import City from city.models import City
from file.models import FileModel, TmpFile from file.models import FileModel, TmpFile
from file.forms import FileModelForm from file.forms import FileModelForm, FileForm
from photologue.forms import PhotoForm from photologue.forms import PhotoForm
# python # python
import random import random
@ -237,9 +237,28 @@ def exposition_change(request, url):
class ExpositionView(AdminView): class ExpositionView(AdminView):
form_class = ExpositionCreateForm form_class = ExpositionCreateForm
model = Exposition model = Exposition
success_url = 'admin/exposition/all/' success_url = '/admin/exposition/all/'
template_name = 'admin/exposition/exposition.html' template_name = 'admin/exposition/exposition.html'
def form_valid(self, form):
StatisticFormSet = formset_factory(StatisticForm)
formset_statistic = StatisticFormSet(self.request.POST)
self.set_obj()
expo = form.save(obj=self.obj)
# delete old halls
Statistic.objects.filter(exposition=getattr(expo, 'id')).delete()
for item in formset_statistic.forms:
# saves new statistic if its valid and not empty
if item.is_valid() and item.has_changed():
statistic = item.save(commit=False)
statistic.exposition = expo
statistic.save()
return HttpResponseRedirect(self.success_url)
def get_form(self, form_class): def get_form(self, form_class):
if self.request.POST: if self.request.POST:
return super(ExpositionView, self).get_form(form_class) return super(ExpositionView, self).get_form(form_class)
@ -256,6 +275,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,
'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,
@ -264,6 +284,9 @@ class ExpositionView(AdminView):
if obj.place: if obj.place:
data['place'] = obj.place.id data['place'] = obj.place.id
if obj.area:
data['area'] = obj.area
data['theme'] = [item.id for item in obj.theme.all()] data['theme'] = [item.id for item in obj.theme.all()]
data['tag'] = ','.join(['%s:%s'%(item.id, item.name) for item in obj.tag.all()]) data['tag'] = ','.join(['%s:%s'%(item.id, item.name) for item in obj.tag.all()])
@ -280,6 +303,12 @@ class ExpositionView(AdminView):
data['main_title_%s' % code] = trans_obj.main_title data['main_title_%s' % code] = trans_obj.main_title
data['time_%s' % code] = trans_obj.time data['time_%s' % code] = trans_obj.time
data['products_%s' % code] = trans_obj.products data['products_%s' % code] = trans_obj.products
data['price_day_%s' % code] = trans_obj.price_day
data['price_all_%s' % code] = trans_obj.price_all
data['price_day_bar_%s' % code] = trans_obj.price_day_bar
data['price_all_bar_%s' % code] = trans_obj.price_all_bar
data['discount_description_%s' % code] = trans_obj.discount_description data['discount_description_%s' % code] = trans_obj.discount_description
data['stat_countries_%s' % code] = trans_obj.stat_countries data['stat_countries_%s' % code] = trans_obj.stat_countries
data['pre_condition_%s' % code] = trans_obj.pre_condition data['pre_condition_%s' % code] = trans_obj.pre_condition
@ -292,7 +321,7 @@ class ExpositionView(AdminView):
form =form_class(initial=data) form =form_class(initial=data)
form.fields['city'].widget.attrs['data-init-text'] = obj.city.name form.fields['city'].widget.attrs['data-init-text'] = obj.city.name
form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.filter(theme__in=data['theme'])] form.fields['tag'].choices = [(item.id, item.name) for item in Tag.objects.language().filter(theme__in=data['theme'])]
return form return form
else: else:
return form_class() return form_class()
@ -301,6 +330,22 @@ class ExpositionView(AdminView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExpositionView, self).get_context_data(**kwargs) context = super(ExpositionView, self).get_context_data(**kwargs)
obj = self.set_obj() obj = self.set_obj()
if obj:
StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',))
# get existing statistic
statistic = Statistic.objects.filter(exposition=getattr(obj, 'id'))
# fill HallFormSet
formset_statistic = StatisticFormSet(queryset=statistic)
context['file_form'] = FileForm(initial={'model': 'exposition.Exposition'})
files = FileModel.objects.filter(content_type=ContentType.objects.get_for_model(obj),object_id=getattr(obj, 'id'))
context['files'] = files
else:
StatisticFormSet = formset_factory(StatisticForm)
formset_statistic = StatisticFormSet()
context['formset_statistic'] = formset_statistic
context['photo_form'] = PhotoForm() context['photo_form'] = PhotoForm()
context['timetable_form'] = TimeTableForm() context['timetable_form'] = TimeTableForm()
context['timetables'] = TimeTable.objects.filter(exposition=obj) context['timetables'] = TimeTable.objects.filter(exposition=obj)

@ -5,14 +5,14 @@ from admin import ExpositionListView, ExpositionView
urlpatterns = patterns('exposition.admin', urlpatterns = patterns('exposition.admin',
url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'), url(r'^upload-photo/(?P<expo_id>.*)/$', 'upload_exposition_photo'),
url(r'^add.*/$', 'exposition_add'), #url(r'^add.*/$', 'exposition_add'),
url(r'^delete/(?P<url>.*)/$', 'exposition_delete'), #url(r'^delete/(?P<url>.*)/$', 'exposition_delete'),
url(r'^change/(?P<url>.*)/$', 'exposition_change'), #url(r'^change/(?P<url>.*)/$', 'exposition_change'),
url(r'^all/$', ExpositionListView.as_view()), url(r'^all/$', ExpositionListView.as_view()),
url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'exposition_switch'), url(r'^switch/(?P<url>.*)/(?P<action>.*)$', 'exposition_switch'),
url(r'^copy/(?P<url>.*)$', 'exposition_copy'), #url(r'^copy/(?P<url>.*)$', 'exposition_copy'),
url(r'^$', ExpositionView.as_view()),
url(r'^(?P<url>.*)/$', ExpositionView.as_view()), url(r'^(?P<url>.*)/$', ExpositionView.as_view()),
url(r'^$', ExpositionView.as_view()),
) )

@ -6,6 +6,7 @@ from tinymce.widgets import TinyMCE
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.forms.util import ErrorList from django.forms.util import ErrorList
from django.core.validators import validate_email, URLValidator from django.core.validators import validate_email, URLValidator
from django.utils.translation import ugettext as _
#models #models
from models import Exposition, TimeTable, TmpTimeTable, AUDIENCE1, CURRENCY, Statistic, BIT_AUDIENCE from models import Exposition, TimeTable, TmpTimeTable, AUDIENCE1, CURRENCY, Statistic, BIT_AUDIENCE
from theme.models import Tag from theme.models import Tag
@ -25,7 +26,8 @@ from functions.form_check import translit_with_separator
from settings.settings import date_formats from settings.settings import date_formats
from functions.admin_forms import AdminFilterForm from functions.admin_forms import AdminFilterForm
places = [(item.id, item.name) for item in PlaceExposition.objects.language().all()]
places.insert(0,('', 'Не выбрано'))
class ExpositionCreateForm(forms.Form): class ExpositionCreateForm(forms.Form):
""" """
Create Exposition form for creating exposition Create Exposition form for creating exposition
@ -41,16 +43,20 @@ class ExpositionCreateForm(forms.Form):
public = [(item1, item2) for item1, item2 in BIT_AUDIENCE] public = [(item1, item2) for item1, item2 in BIT_AUDIENCE]
currencies = [(item, item) for item in CURRENCY] currencies = [(item, item) for item in CURRENCY]
data_begin = forms.DateField(label=u'Дата начала') data_begin = forms.DateField(label=u'Дата начала', input_formats=['%Y-%m-%d', '%d.%m.%Y'])
data_end = forms.DateField(label=u'Дата окночания') 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.ModelMultipleChoiceField(label=u'Организаторы', queryset=Organiser.objects.all(), required=False) organiser = forms.MultipleChoiceField(label=u'Организаторы', required=False,
company = forms.ModelMultipleChoiceField(label=u'Компании', queryset=Company.objects.all(), required=False) choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
country = forms.ModelChoiceField(label=u'Страна', queryset=Country.objects.all(), empty_label=None)
theme = forms.ModelMultipleChoiceField(label=u'Тематики', queryset=Theme.objects.all()) company = forms.MultipleChoiceField(label=u'Компании', required=False,
place = forms.ModelChoiceField(label=u'Место проведения', queryset=PlaceExposition.objects.all(), choices=[(item.id, item.name) for item in Company.objects.language().all()] )
empty_label='', required=False) country = forms.ChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()])
theme = forms.MultipleChoiceField(label='Тематики',
choices=[(item.id, item.name) for item in Theme.objects.language().all()])
place = forms.ChoiceField(label=u'Место проведения', required=False,
choices=places)
#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)
@ -59,11 +65,13 @@ class ExpositionCreateForm(forms.Form):
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)
web_page = forms.CharField(label=u'Веб страница', required=False) web_page = forms.CharField(label=u'Веб страница', required=False)
registration_link = forms.CharField(label=u'Ссылка на регистрацию', required=False)
foundation_year = forms.CharField(label=u'Год основания', required=False) foundation_year = forms.CharField(label=u'Год основания', required=False)
members = forms.CharField(label=u'Участники', required=False) members = forms.CharField(label=u'Участники', required=False)
visitors = forms.CharField(label=u'Посетители', required=False) visitors = forms.CharField(label=u'Посетители', required=False)
min_area = forms.CharField(label=u'Минимальная плошадь', required=False) min_area = forms.CharField(label=u'Минимальная площадь', required=False)
discount = forms.CharField(label=u'Cкидка(%)', required=False) discount = forms.CharField(label=u'Cкидка(%)', required=False)
area = forms.CharField(label=u'Площадь', required=False)
quality_label = forms.MultipleChoiceField(label=u'Метки', required=False, quality_label = forms.MultipleChoiceField(label=u'Метки', required=False,
choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')], choices=[('ufi', 'UFI'), ('rsva', 'РСВЯ'), ('exporating', 'ExpoRating')],
widget=forms.CheckboxSelectMultiple()) widget=forms.CheckboxSelectMultiple())
@ -72,10 +80,10 @@ class ExpositionCreateForm(forms.Form):
application_deadline = forms.DateField(label=u'Срок подачи стэнда', required=False) application_deadline = forms.DateField(label=u'Срок подачи стэнда', required=False)
min_stand_size = forms.CharField(label=u'Минимальный размер стэнда', required=False) min_stand_size = forms.CharField(label=u'Минимальный размер стэнда', required=False)
price_day = forms.CharField(label=u'Цена за 1 день', required=False) #price_day = forms.CharField(label=u'Цена за 1 день', required=False)
price_all = forms.CharField(label=u'Цена за все дни', required=False) #price_all = forms.CharField(label=u'Цена за все дни', required=False)
price_day_bar = forms.CharField(label=u'Цена на стойке 1 день', required=False) #price_day_bar = forms.CharField(label=u'Цена на стойке 1 день', required=False)
price_all_bar = forms.CharField(label=u'Цена на стойке все дни', required=False) #price_all_bar = forms.CharField(label=u'Цена на стойке все дни', required=False)
price_catalog = forms.CharField(label=u'Цена за каталог', required=False) price_catalog = forms.CharField(label=u'Цена за каталог', required=False)
tax = forms.BooleanField(label=u'Налог включен', initial=True, required=False) tax = forms.BooleanField(label=u'Налог включен', initial=True, required=False)
min_closed_area = forms.CharField(label=u'Минимальная цена закрытой НЕ оборудованной площади', required=False) min_closed_area = forms.CharField(label=u'Минимальная цена закрытой НЕ оборудованной площади', required=False)
@ -114,6 +122,17 @@ class ExpositionCreateForm(forms.Form):
required=False, widget=CKEditorWidget) required=False, widget=CKEditorWidget)
self.fields['time_%s' % code] = forms.CharField(label=u'Время работы', self.fields['time_%s' % code] = forms.CharField(label=u'Время работы',
required=False, widget=CKEditorWidget) required=False, widget=CKEditorWidget)
self.fields['price_day_%s' % code] = forms.CharField(label=u'Стоимость билета 1 день', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['price_all_%s' % code] = forms.CharField(label=u'Стоимость билета все дни', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['price_day_bar_%s' % code] = forms.CharField(label=u'Стоимость на стойке 1 день', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['price_all_bar_%s' % code] = forms.CharField(label=u'Стоимость на стойке все дни', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['products_%s' % code] = forms.CharField(label=u'Экспонируемые продукты', self.fields['products_%s' % code] = forms.CharField(label=u'Экспонируемые продукты',
required=False, widget=CKEditorWidget) required=False, widget=CKEditorWidget)
self.fields['discount_description_%s' % code] = forms.CharField(label=u'Описание скидки', self.fields['discount_description_%s' % code] = forms.CharField(label=u'Описание скидки',
@ -136,11 +155,6 @@ class ExpositionCreateForm(forms.Form):
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['descriptions_%s' % code] = forms.CharField(label=u'Meta description', required=False, max_length=255, self.fields['descriptions_%s' % code] = forms.CharField(label=u'Meta description', required=False, max_length=255,
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
#creates select inputs ind fill it
#!service has bitfield. uncomment when country data will be filled
#services = [(item.id, item.name) for item in Service.objects.all()]
#self.fields['service'] = forms.MultipleChoiceField(label='Услуги', choices=services, required=False)
def save(self, obj=None): def save(self, obj=None):
""" """
@ -162,24 +176,24 @@ class ExpositionCreateForm(forms.Form):
#simple fields #simple fields
exposition.url = translit_with_separator(data['name_ru'].strip()).lower() exposition.url = translit_with_separator(data['name_ru'].strip()).lower()
exposition.logo = data['logo'] if data.get('logo'):
exposition.logo = data['logo']
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']
exposition.web_page= data['web_page'] exposition.web_page= data['web_page']
exposition.registration_link = data['registration_link']
exposition.foundation_year = data['foundation_year'] exposition.foundation_year = data['foundation_year']
exposition.members = data['members'] exposition.members = data['members']
exposition.visitors = data['visitors'] exposition.visitors = data['visitors']
exposition.area = data['area']
exposition.min_area = data['min_area'] exposition.min_area = data['min_area']
exposition.currency = data['currency'] exposition.currency = data['currency']
exposition.application_deadline = data['application_deadline'] exposition.application_deadline = data['application_deadline']
exposition.min_stand_size = data['min_stand_size'] exposition.min_stand_size = data['min_stand_size']
exposition.price_day = data['price_day']
exposition.price_all = data['price_all']
exposition.price_all_bar = data['price_all_bar']
exposition.price_day_bar = data['price_day_bar']
exposition.price_catalog = data['price_catalog'] exposition.price_catalog = data['price_catalog']
exposition.tax = data['tax'] exposition.tax = data['tax']
exposition.min_closed_area = data['min_closed_area'] exposition.min_closed_area = data['min_closed_area']
@ -207,36 +221,26 @@ class ExpositionCreateForm(forms.Form):
exposition.audience = audience exposition.audience = audience
if data.get('country'): exposition.country = Country.objects.get(id=data['country'])
exposition.country = Country.objects.get(id=data['country'].id)#.id cause select uses queryset exposition.city = City.objects.get(id=data['city'])
if data.get('city'):
exposition.city = City.objects.get(id=data['city'])
if data.get('place'): if data.get('place'):
exposition.place = PlaceExposition.objects.get(id=data['place'].id)#.id cause select uses queryset exposition.place = PlaceExposition.objects.get(id=data['place'])
# fill translated fields and save object # fill translated fields and save object
fill_with_signal(Exposition, exposition, data) fill_with_signal(Exposition, exposition, data)
#fill manytomany fields #fill manytomany fields
for item in data['theme']:
exposition.theme.add(item.id)#.id cause select uses queryset 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']))
#for item in data['tag']: exposition.organiser.add(*Organiser.objects.filter(id__in=data.get('organiser', [])))
# exposition.tag.add(item) exposition.company.add(*Company.objects.filter(id__in=data.get('company', [])))
# uses because in the next loop data will be overwritten
for item in data['organiser']:
exposition.organiser.add(item)
for item in data['company']:
exposition.company.add(item)
exposition.save() exposition.save()
# save files
check_tmp_files(exposition, data.get('key'))
check_tmp_timetables(exposition, data.get('key'))
return exposition return exposition
def clean(self): def clean(self):
@ -280,6 +284,30 @@ class ExpositionCreateForm(forms.Form):
raise forms.ValidationError(e.messages[0]) raise forms.ValidationError(e.messages[0])
return web_page return web_page
def clean_registration_link(self):
"""
checking web_page
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
registration_link = cleaned_data.get('registration_link')
if not registration_link:
return ''
validate = URLValidator()
try:
validate(registration_link)
except(forms.ValidationError),e:
raise forms.ValidationError(e.messages[0])
return registration_link
def clean_area(self):
"""
checking foundation_year
"""
cleaned_data = super(ExpositionCreateForm, self).clean()
area = cleaned_data.get('area').strip()
return is_positive_integer(area)
def clean_foundation_year(self): def clean_foundation_year(self):
""" """
checking foundation_year checking foundation_year
@ -438,6 +466,7 @@ class StatisticForm(forms.ModelForm):
year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'})) year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}))
visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False)
members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False) members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False)
area = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False)
class Meta: class Meta:
model = Statistic model = Statistic
exclude = ('exposition') exclude = ('exposition')
@ -464,9 +493,8 @@ class TimeTableForm(forms.Form):
widget=forms.TextInput(attrs={'style':'width: 150px'})) widget=forms.TextInput(attrs={'style':'width: 150px'}))
end = forms.DateTimeField(label='Время окончания', input_formats=date_formats, end = forms.DateTimeField(label='Время окончания', input_formats=date_formats,
widget=forms.TextInput(attrs={'style':'width: 150px'})) widget=forms.TextInput(attrs={'style':'width: 150px'}))
timetable_organiser = forms.ModelChoiceField(label='Организатор', queryset=Organiser.objects.all(), empty_label='', required=False) timetable_organiser = forms.ChoiceField(label='Организатор', required=False,
# uses for comparing with TmpTimetable key choices=[(item.id, item.name) for item in Organiser.objects.language().all()])
key = forms.CharField(required=False, widget=forms.HiddenInput())
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
@ -484,7 +512,7 @@ class TimeTableForm(forms.Form):
self.fields['name_%s' % code] = forms.CharField(label='Название программы', required=required, self.fields['name_%s' % code] = forms.CharField(label='Название программы', required=required,
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['programe_%s' % code] = forms.CharField(label='Программа', required=required, self.fields['programe_%s' % code] = forms.CharField(label='Программа', required=required,
widget=TinyMCE()) widget=CKEditorWidget)
self.fields['speaker_%s' % code] = forms.CharField(label='Спикеры', required=False, self.fields['speaker_%s' % code] = forms.CharField(label='Спикеры', required=False,
widget=forms.TextInput(attrs={'style':'width: 550px'})) widget=forms.TextInput(attrs={'style':'width: 550px'}))
self.fields['place_%s' % code] = forms.CharField(label='Место проведения', required=False, self.fields['place_%s' % code] = forms.CharField(label='Место проведения', required=False,
@ -493,14 +521,13 @@ class TimeTableForm(forms.Form):
def save(self,exposition=None): def save(self,exposition=None):
data = self.cleaned_data data = self.cleaned_data
if not exposition: if not exposition:
timetable = TmpTimeTable() return None
timetable.key = data.get('key')
else: else:
timetable = TimeTable() timetable = TimeTable()
# simple fields # simple fields
if data.get('timetable_organiser'): if data.get('timetable_organiser'):
timetable.timetable_organiser = data['timetable_organiser'] timetable.timetable_organiser_id = data['timetable_organiser']
timetable.exposition = exposition timetable.exposition = exposition
timetable.begin = data.get('begin') timetable.begin = data.get('begin')
timetable.end = data.get('end') timetable.end = data.get('end')
@ -513,5 +540,40 @@ class TimeTableForm(forms.Form):
return timetable return timetable
monthes = [('', ''),
(1, _(u'Январь')), (2, _(u'Февраль')), (3, _(u'Март')), (4, _(u'Апрель')),
(5, _(u'Май')), (6, _(u'Июнь')), (7, _(u'Июль')), (8, _(u'Август')),
(9, _(u'Сентябрь')), (10, _(u'Октябрь')), (11, _(u'Ноябрь')), (12, _(u'Декабрь'))]
class ExpositionFilterForm(AdminFilterForm): class ExpositionFilterForm(AdminFilterForm):
model = Exposition model = Exposition
country = forms.MultipleChoiceField(label=u'Страна', choices=[(c.id, c.name) for c in Country.objects.all()],
required=False)
#city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False)
year = forms.CharField(label=u'Год', required=False)
month = forms.ChoiceField(label=u'Месяц',choices=[(item[0], item[1]) for item in monthes], required=False)
def filter(self):
data = self.cleaned_data
qs = super(ExpositionFilterForm, self).filter()
exact_name = data['exact_name']
if exact_name:
return self.model.objects.filter(translations__name=exact_name).distinct()
country = data['country']
# city = data['city']
year = data['year']
month = data['month']
if country:
qs = qs.filter(country__in=country)
# if city:
# qs = qs.filter(city__in=city)
if year:
qs = qs.filter(data_begin__year=year)
if month:
qs = qs.filter(data_begin__month=month)
return qs

@ -1,10 +1,5 @@
from django.core.management.base import BaseCommand, CommandError from django.core.management.base import BaseCommand, CommandError
from exposition.models import Exposition from exposition.models import Exposition
from django.contrib.sites.models import Site
from photologue.models import Gallery, Photo
from file.models import FileModel
from django.core.files import File
from django.core.files.temp import NamedTemporaryFile
import urllib2 import urllib2
from django.conf import settings from django.conf import settings
from django.utils import translation from django.utils import translation

@ -1,396 +1,85 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand, CommandError import xlrd
from city.models import City from django.core.management.base import BaseCommand
from country.models import Country
from exposition.models import Exposition
import xlrd, xlwt
#from import_xls.excel_settings import event_sett
from django.conf import settings
from import_xls.import_forms import google_address
def to_int(val):
"""
Reverse function to get_int
return None if value isnt integer
"""
try:
return int(val)
except ValueError:
return None
def to_country(value):
try:
#query = get_translation_aware_manager(Country)
#country = query.filter(name=value)[0]
country = Country.objects.filter(translations__name=value.strip())[0]
return country
except IndexError:
return None
def to_city(value, lang, country):
try:
# get city by name
#objects = get_translation_aware_manager(City)
# except IndexError if no found
city = City.objects.filter(translations__name=value.strip(), country=country)[0]
return city
except IndexError:
return None
from theme.models import Theme, Tag
def to_theme(obj, value):
if isinstance(value, float) or isinstance(value, int):
if (value - int(value) > 0):
value = str(value)
else:
value = str(int(value))
theme_ids = value.split('.')
else:
theme_ids = value.split(',')
theme_objects = []
for id in theme_ids:
try:
theme = Theme.objects.language('ru').get(id=int(id))
theme_objects.append(theme)
obj.theme.add(theme)
except Theme.DoesNotExist, ValueError:
pass
return theme_objects
from hvad.utils import get_translation_aware_manager
def to_tag(obj,value):
if value == [""]:
return None
names = value.split(',')
tags = []
for name in names:
objects = get_translation_aware_manager(Tag)
tag = objects.filter(name=name)
#tag = Tag.objects.language('ru').filter(transations__name=name)
if tag:
tags.append(tag[0])
obj.tag.add(tag[0])
else:
continue
return tags
import time
def to_date(value):
if not value:
return None
if isinstance(value, unicode) or isinstance(value, str):
t = time.strptime(value, "%d.%m.%Y")
if isinstance(value, float):
t = xlrd.xldate_as_tuple(value, 0)+(0,0,0)
return time.strftime("%Y-%m-%d", t)
def to_currency(value):
if value=='USD':
return value
if value=='EUR':
return value
if value=='RUB':
return 'RUB'
return 'USD'
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)
except:
return ''
return email
from file.models import FileModel
import urllib2
from django.conf import settings from django.conf import settings
from django.contrib.contenttypes.models import ContentType from exposition.models import Exposition
from functions.files import get_alternative_filename from import_xls.excel_settings import event_sett
def save_logo(obj, value, purpose):
"""
if not obj.id:
return None
"""
urls = value.split(';')
for url in urls:
if url[0]!=('/'):
url = '/'+url
url = 'http://www.expomap.ru'+url
file_name = url.split('/')[-1]
alt_name = get_alternative_filename(settings.MEDIA_ROOT+'imgs/', file_name)
download_to = settings.MEDIA_ROOT+'imgs/'+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 ='imgs/'+alt_name
content_type = ContentType.objects.get_for_model(obj)
file = FileModel(file_path=file_name, file_type='JPG', purpose=purpose,
content_type=content_type, object_id=obj.id)
file.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):
return value
else:
deduct = ('-','(',')','.',' ', '+')
for elem in deduct:
value = value.replace(elem, '')
value = to_int(value)
return value
from place_exposition.models import PlaceExposition
def to_place(value):
try:
place = PlaceExposition.objects.get(id=value)
return place
except:
return None
from exposition.models import BIT_AUDIENCE
def to_audience(value, model=Exposition):
if value:
l = value.split(', ')
aud = {'Trade visitors':'experts', 'Trade visitors and Public':'experts and consumers',
'General public': 'general public'}
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if aud.get(value) == item2:
new_list.append(item1)
if new_list:
return reduce(lambda x,y: x|y, (getattr(model.audience, item) for item in new_list))
return 0
def to_periodic(value):
per = {'Оnce a year': 1.0, 'Every 2 years':0.5, 'Twice a year':2.0}
return per.get(value, 0)
from organiser.models import Organiser
def to_organiser(obj, value):
org = Organiser.objects.filter(translations__name=value)
if org:
obj.organiser.add(org[0])
else:
org = Organiser()
org.translate('ru')
org.name = value
org.save()
event_sett = {
u'ID':{u'field': u'id', u'func': to_int},
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', 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'organiser', u'func': to_organiser, u'method': True},####
u'Организатор №2':{u'field': u'organiser', u'func': to_organiser, u'method': True},####
u'Описание события':{u'field': u'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'logo', u'func': save_logo, u'method': True, u'purpose': 'logo'},
u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url},
u'Экспонируемые продукты':{u'field': u'products', u'func': unicode},
u'Время работы':{u'field': u'time', u'func': unicode},
u'Валюта':{u'field': u'currency', u'func': to_currency},
#
u'Посетители_билет (1 день)':{u'field': u'price_day', u'func': to_int},
u'Посетители_билет (все дни)':{u'field': u'price_all', u'func': to_int},
#u'Условия':{u'field': u'periodic', u'func': unicode},
u'Посетители_билет (1 день)(на стойке)':{u'field': u'price_day_bar', u'func': to_int},##??
u'Посетители_билет (все дни)(на стойке)':{u'field': u'price_all_bar', u'func': to_int},##??
#u'Условия':{u'field': u'periodic', u'func': unicode},##??
#u'Примечание':{u'field': u'periodic', 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'periodic', u'func': unicode},##??
u'Площадь':{u'field': u'periodic', 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_open_area', u'func': to_int},
u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int},
#u'Примечание':{u'field': u'periodic', u'func': unicode},
u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date},
u'UFI':{u'field': u'quality_label', u'func': bool, },##
u'РСВЯ':{u'field': u'quality_label', u'func': bool},##
u'EXPORATING':{u'field': u'quality_label', u'func': bool},##
u'Отменена':{u'field': u'canceled', u'func': bool},
u'ExpoHIT':{u'field': u'expohit', u'func': bool},
#u'Фото':{u'field': u'photo', u'func': save_photo, u'method': True},
} CHINA_FILE = settings.MEDIA_ROOT+'/import/expo_china_ru.xlsx'
GERMANY_FILE = settings.MEDIA_ROOT+'/import/expo_germany_ru.xlsx'
# 391 row not imported(same url)
ITALY_FILE = settings.MEDIA_ROOT+'/import/expo_italy_ru.xlsx'
# moscow 3 exps
F = settings.MEDIA_ROOT+'/import/exp.xlsx'
class Command(BaseCommand): class Command(BaseCommand):
def handle(self, *args, **options): def handle(self, *args, **options):
f = open(settings.MEDIA_ROOT+'/import/Places Eng Upd.xlsx', 'r') f = open(F, 'r')
book = xlrd.open_workbook(file_contents=f.read()) book = xlrd.open_workbook(file_contents=f.read())
sheet = book.sheet_by_index(0) sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
labels = [label for label in row_list[0]] labels = [label for label in row_list[0]]
print(123)
for row_number, row in enumerate(row_list[1:]):
if row[0] != '':
for row_number, row in enumerate(row_list): # in first column ids
# go through all rows in file try:
if row_number > 0: object = Exposition.objects.language('ru').get(id=int(row[0]))
# first field is label except ValueError:
if row[0] != '':
# in first column ids
try:
object = Exposition.objects.language('en').get(id=int(row[0]))
except ValueError:
object = Exposition()
object.translate('en')
except Exposition.DoesNotExist:
object = Exposition(id= int(row[0]))
object.translate('en')
else:
# if id blank - its a new place
object = Exposition() object = Exposition()
object.translate('ru')
except Exposition.DoesNotExist:
object = Exposition(id= int(row[0]))
object.translate('ru')
else:
# if id blank - its a new place
object = Exposition()
object.translate('ru')
methods = []
for col_number, cell in enumerate(row):
label = labels[col_number]
setting = event_sett.get(label)
if setting is None:
continue
if setting.get('method'):
if cell != "":
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
continue
field_name = setting['field']
func = setting.get('func')
if func is not None:
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, theme, 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)
value = func(cell, 'ru', getattr(object, extra_value))
elif setting.get('bitfield'):
value = func(object, cell, setting['label'])
object.translate('en') else:
methods = [] value = func(cell)
flag = False setattr(object, field_name, value)
for col_number, cell in enumerate(row): object.save()
# go through row cells
# field name current cell
label = labels[col_number]
setting = event_sett.get(label)
if setting is None:
continue
if setting.get('method'):
if cell != "":
methods.append({'func': setting['func'], 'value': cell, 'purpose': setting.get('purpose')})
continue
field_name = setting['field']
func = setting.get('func')
if func is not None:
extra_value = setting.get('extra_values')
if extra_value is not None:
# if setting has extra value then
# it is some field like city, theme, 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)
value = func(cell, 'en', getattr(object, extra_value))
else:
value = func(cell)
#if field_name =='adress':
# setattr(object, 'address', google_address(value))
if field_name=='city' and not value:
print('error city')
flag = True
continue
if not field_name=='quality_label':
setattr(object, field_name, value)
else:
if value:
if setting.get('l') == 'ufi':
object.quality_label.ufi = True
if setting.get('l') == 'rsva':
object.quality_label.rsva = True
if setting.get('l') == 'exporating':
object.quality_label.exporating = True
print('post save %s'% str(object))
if not flag: for method in methods:
object.save() func = method['func']
""" if method.get('purpose'):
try: try:
print('pre save %s'% str(object)) func(object, method['value'], method['purpose'])
object.save()
except: except:
print('saving error')
continue continue
"""
print('post save %s'% str(object))
else: else:
print('bad city') func(object, method['value'])
for method in methods:
func = method['func']
if method.get('purpose'):
try:
func(object, method['value'], method['purpose'])
except:
continue
else:
try:
func(object, method['value'])
except:
continue

@ -1,9 +1,12 @@
import datetime
from hvad.models import TranslationManager from hvad.models import TranslationManager
class ClientManager(TranslationManager): class ClientManager(TranslationManager):
def get_query_set(self): def get_query_set(self):
return super(ClientManager, self).get_query_set().filter(is_published=True) now = datetime.datetime.now().date()
return super(ClientManager, self).get_query_set().filter(is_published=True, data_begin__gte=now).order_by('data_begin')
""" """

@ -3,22 +3,22 @@ import copy, datetime
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.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.utils import translation
from django.conf import settings from django.conf import settings
from hvad.models import TranslatableModel, TranslatedFields, TranslationManager from hvad.models import TranslatableModel, TranslatedFields, TranslationManager
from django.contrib.contenttypes import generic from django.contrib.contenttypes import generic
from bitfield import BitField from bitfield import BitField
from service.models import Service from service.models import Service
from functions.db import db_table_exists from functions.db import db_table_exists
from organiser.models import Organiser from organiser.models import Organiser
from manager import ClientManager from manager import ClientManager
#
from functions.custom_fields import EnumField from functions.custom_fields import EnumField
from functions.signal_handlers import post_save_handler, pre_save_handler from functions.signal_handlers import post_save_handler, pre_save_handler
from functions.models_methods import ExpoManager from functions.models_methods import ExpoManager
from functions.model_mixin import EventMixin, ExpoMixin from functions.model_mixin import EventMixin, ExpoMixin
from functions.translate import fill_with_signal from functions.translate import fill_with_signal
from photologue.models import Gallery from photologue.models import Gallery
from import_xls.model_utils import ExpoImportManager
AUDIENCE1 = ((None,_(u'Не выбрано')), AUDIENCE1 = ((None,_(u'Не выбрано')),
('experts', _(u'Специалисты')), ('experts', _(u'Специалисты')),
@ -32,7 +32,7 @@ BIT_AUDIENCE = (('experts', _(u'Специалисты')), ('experts and consume
('general public', _(u'Широкая публика'))) ('general public', _(u'Широкая публика')))
CURRENCY = ('RUB', 'USD', 'EUR') CURRENCY = ('RUB', 'USD', 'EUR', 'RMB', 'GBP')
# check if table exist and create flags if true # check if table exist and create flags if true
flags = [str(item.id) for item in Service.objects.all()] if db_table_exists('service_service') else [] flags = [str(item.id) for item in Service.objects.all()] if db_table_exists('service_service') else []
@ -44,11 +44,14 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
Uses hvad.TranslatableModel which is child of django.db.models class Uses hvad.TranslatableModel which is child of django.db.models class
""" """
# main
catalog = '/expo/' catalog = '/expo/'
catalog_name = _(u'Выставки:')
search_name = None
# type of event
event_type = 'expo'
url = models.SlugField(unique=True) url = models.SlugField(unique=True, max_length=255)
#logo = fo
data_begin = models.DateField(verbose_name='Дата начала') data_begin = models.DateField(verbose_name='Дата начала')
data_end = models.DateField(verbose_name='Дата окончания') data_end = models.DateField(verbose_name='Дата окончания')
services = BitField(flags=flags) services = BitField(flags=flags)
@ -100,11 +103,15 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
discount_description = models.TextField(verbose_name='Описание скидки', blank=True), discount_description = models.TextField(verbose_name='Описание скидки', blank=True),
time = models.TextField(verbose_name='Время работы', blank=True), time = models.TextField(verbose_name='Время работы', blank=True),
# visit and particaption data # visit and particaption data
price_day = models.CharField(verbose_name='Стоимость билета 1 день', max_length=255, blank=True),
price_all = models.CharField(verbose_name='Стоимость билета все дни', max_length=255, blank=True),
price_day_bar = models.CharField(verbose_name='Стоимость на стойке 1 день', max_length=255, blank=True),
price_all_bar = models.CharField(verbose_name='Стоимость на стойке все дни', max_length=255, blank=True),
stat_countries = models.TextField(verbose_name='Участвующие страны', blank=True), stat_countries = models.TextField(verbose_name='Участвующие страны', blank=True),
pre_condition = models.CharField(verbose_name='Условия предварительной регистрации', max_length=255, blank=True), pre_condition = models.CharField(verbose_name='Условия предварительной регистрации', max_length=255, blank=True),
stand_condition = models.CharField(verbose_name='Условия регистрации на стойке', max_length=255, blank=True), stand_condition = models.CharField(verbose_name='Условия регистрации на стойке', max_length=255, blank=True),
visit_note = models.CharField(verbose_name='Примечание по посещению', max_length=255, blank=True), visit_note = models.CharField(verbose_name='Примечание по посещению', max_length=255, blank=True),
participation_note = models.CharField(verbose_name='Примечание по участии', max_length=255, blank=True), participation_note = models.TextField(verbose_name='Примечание по участии', blank=True),
#-----meta data #-----meta data
@ -114,25 +121,20 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
) )
files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id') files = generic.GenericRelation('file.FileModel', content_type_field='content_type', object_id_field='object_id')
note = generic.GenericRelation('note.Note', content_type_field='content_type', object_id_field='object_id')
#about #about
periodic = models.FloatField(verbose_name='Переодичность', blank=True, null=True) periodic = models.FloatField(verbose_name='Переодичность', blank=True, null=True)
audience = BitField(flags=[k for k, v in BIT_AUDIENCE]) audience = BitField(flags=[k for k, v in BIT_AUDIENCE])
web_page = models.CharField(verbose_name='Вебсайт', max_length=255, blank=True) web_page = models.CharField(verbose_name='Вебсайт', max_length=255, blank=True)
foundation_year = models.PositiveIntegerField(verbose_name='Год основания', blank=True, null=True) foundation_year = models.PositiveIntegerField(verbose_name='Год основания', blank=True, null=True)
area = models.PositiveIntegerField(verbose_name='Площадь', blank=True, null=True)
# conditions of Participation # conditions of Participation
registration_link = models.URLField(verbose_name='Ссылка на регистрацию', max_length=255, blank=True) registration_link = models.URLField(verbose_name='Ссылка на регистрацию', max_length=255, blank=True)
min_area = models.PositiveIntegerField(verbose_name='Минимальная площадь', blank=True, null=True) min_area = models.PositiveIntegerField(verbose_name='Минимальная площадь', blank=True, null=True)
currency = EnumField(values=CURRENCY, default='USD') currency = EnumField(values=CURRENCY, default='USD')
application_deadline = models.DateField(verbose_name='Срок подачи заявки', null=True) application_deadline = models.DateField(verbose_name='Срок подачи заявки', null=True)
min_stand_size = models.PositiveIntegerField(verbose_name='Минимальный размер стэнда', blank=True, null=True) min_stand_size = models.PositiveIntegerField(verbose_name='Минимальный размер стэнда', blank=True, null=True)
price_day = models.PositiveIntegerField(verbose_name='Стоимость билета 1 день', blank=True, null=True)
price_all = models.PositiveIntegerField(verbose_name='Стоимость билета все дни', blank=True, null=True)
# Условие
price_day_bar = models.PositiveIntegerField(verbose_name='Стоимость на стойке 1 день', blank=True, null=True)
price_all_bar = models.PositiveIntegerField(verbose_name='Стоимость на стойке все дни', blank=True, null=True)
# условие
# примечание
price_catalog = models.PositiveIntegerField(verbose_name='Стоимость каталога', blank=True, null=True) price_catalog = models.PositiveIntegerField(verbose_name='Стоимость каталога', blank=True, null=True)
tax = models.BooleanField(verbose_name='Налог', default=1) tax = models.BooleanField(verbose_name='Налог', default=1)
min_closed_area = models.PositiveIntegerField(verbose_name='Минимальная цена закрытой НЕ оборудованной площади', min_closed_area = models.PositiveIntegerField(verbose_name='Минимальная цена закрытой НЕ оборудованной площади',
@ -148,12 +150,10 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
max_open_area = models.PositiveIntegerField(verbose_name='Максимальная цена открытой площади', max_open_area = models.PositiveIntegerField(verbose_name='Максимальная цена открытой площади',
blank=True, null=True) blank=True, null=True)
registration_payment = models.PositiveIntegerField(verbose_name='Регистрационный взнос', blank=True, null=True) registration_payment = models.PositiveIntegerField(verbose_name='Регистрационный взнос', blank=True, null=True)
# примечание
# statistic
enable = ClientManager() enable = ClientManager()
imports = ExpoImportManager()
#set manager of this model #set manager of this model
objects = ExpoManager() objects = ExpoManager()
@ -161,6 +161,26 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
def __unicode__(self): def __unicode__(self):
return self.lazy_translation_getter('name', unicode(self.pk)) return self.lazy_translation_getter('name', unicode(self.pk))
def get_parent(self):
return {}
def get_index_text(self):
translation.activate('ru')
translations = self.translations.all()
names = ' '.join([tr.name for tr in translations])
titles = ' '.join([tr.main_title for tr in translations])
themes = ' '.join([' '.join(theme.get_all_names()) for theme in self.theme.all()])
tags = ' '.join([' '.join(tag.get_all_names()) for tag in self.tag.all()])
return names + ' ' + titles + ' ' + themes + ' ' + tags
def get_note_by_user(self, user_id):
note = self.note.filter(user__id=user_id)
try:
return note.get().text
except:
return ''
def upload_photo_url(self): def upload_photo_url(self):
return '/admin/exposition/upload-photo/%s/'%self.id return '/admin/exposition/upload-photo/%s/'%self.id
@ -184,6 +204,12 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return gallery return gallery
def tags(self):
return self.tag.language().all()
def statistic_exists(self):
return Statistic.objects,filter(exposition=self).exists()
def upload_photo(self, photo ,gallery=None): def upload_photo(self, photo ,gallery=None):
""" """
@ -195,9 +221,9 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
gallery.photos.add(photo) gallery.photos.add(photo)
def get_index_text(self): # def get_index_text(self):
names = [tr.name for tr in self.translations.all()] # names = [tr.name for tr in self.translations.all()]
return names # return names
def get_audience(self): def get_audience(self):
checked = [item for item, bool in self.audience if bool==True] checked = [item for item, bool in self.audience if bool==True]
@ -250,6 +276,14 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin):
return days return days
def get_currency_html(self):
cur = self.currency
currency_codes = {'EUR':'', 'USD':'$', 'RUB':'ք'}
code = currency_codes.get(cur)
if code:
return code
return cur
def clone(self): def clone(self):
""" """
Return an identical copy of the instance with a new ID. Return an identical copy of the instance with a new ID.
@ -298,6 +332,7 @@ class Statistic(models.Model):
year = models.PositiveIntegerField(verbose_name='Год') year = models.PositiveIntegerField(verbose_name='Год')
members = models.PositiveIntegerField(verbose_name='Посетители') members = models.PositiveIntegerField(verbose_name='Посетители')
visitors = models.PositiveIntegerField(verbose_name='Участники') visitors = models.PositiveIntegerField(verbose_name='Участники')
area = models.PositiveIntegerField(verbose_name='Площадь')
from django.core import serializers from django.core import serializers
from functions.models_methods import hvad_to_dict from functions.models_methods import hvad_to_dict

@ -1,10 +1,14 @@
# -*- coding: utf-8 -*-
from django.utils import translation
from haystack import indexes from haystack import indexes
from models import Exposition from models import Exposition
from functions.search_mixin import ExpoSearchMixin
class ExpositionIndex(indexes.SearchIndex, indexes.Indexable): class ExpositionIndex(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()
data_begin = indexes.DateField(model_attr='data_begin') data_begin = indexes.DateField(model_attr='data_begin')
data_end = indexes.DateField(model_attr='data_end') data_end = indexes.DateField(model_attr='data_end')
theme = indexes.MultiValueField() theme = indexes.MultiValueField()
@ -12,27 +16,22 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable):
country_id = indexes.IntegerField() country_id = indexes.IntegerField()
city_id = indexes.IntegerField() city_id = indexes.IntegerField()
area_id = indexes.IntegerField() area_id = indexes.IntegerField()
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_area_id(self, obj): def prepare_form_name(self, obj):
return obj.country.area.id return None
def prepare_country_id(self, obj): def prepare_catalog_name_en(self, obj):
return obj.country.id return u'Expos'
def prepare_city_id(self, obj): def prepare_catalog_name_ru(self, obj):
return obj.city.id return u'Выставки'
def prepare_theme(self, obj):
return [th.id for th in obj.theme.filter()]
def prepare_tag(self, obj):
return [th.id for th in obj.tag.filter()]
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 Exposition return Exposition
@ -40,3 +39,13 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable):
def index_queryset(self, using=None): def index_queryset(self, using=None):
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

@ -1,34 +1,80 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.conf.urls import patterns, include, url from django.conf.urls import patterns, include, url
from views import ExpositionView, ExpositionVisitors, ExpositionMembers, ExpositionStatistic, ExpositionPrice,\ from views import ExpositionStatistic, ExpositionPrice,\
ExpositionProgramme, ExpositionSearchView, ExpositionByCountry, ExpositionByTheme, ExpositionByCity ExpositionProgramme, ExpositionSearchView, ExpositionByCountry, ExpositionByTheme, ExpositionByCity
from django.http import HttpResponse
from django.http import HttpResponse
from views import ExpositionServiceView from views import ExpositionServiceView
from views import ExpoCountryCatalog, ExpoCityCatalog, ExpoThemeCatalog, ExpoTagCatalog, ExpoList, ExpoDetail,\
ExpoVisitors, ExpoMembers
def test(request):
return HttpResponse('123')
urlpatterns = patterns('', urlpatterns = patterns('',
# search
url(r'expo/search/', ExpositionSearchView.as_view()), url(r'expo/search/', ExpositionSearchView.as_view()),
url(r'expo/country/', ExpositionByCountry.as_view()), # country catalog
url(r'expo/city/', ExpositionByCity.as_view()), url(r'expo/country/$', ExpositionByCountry.as_view()),
url(r'expo/theme/', ExpositionByTheme.as_view()), url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view()),
url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view()),
url(r'expo/(?P<params>.*)/(?P<page>\d+)/$', ExpositionView.as_view()), url(r'expo/country/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoCountryCatalog.as_view()),
url(r'expo/(?P<page>\d+)/$', ExpositionView.as_view()), url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoCountryCatalog.as_view()),
# url(r'expo/country/(?P<slug>.*)/(?P<year>\d+)/$', ExpoCountryCatalog.as_view()),
url(r'expo/(?P<params>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()), url(r'expo/country/(?P<slug>.*)/$', ExpoCountryCatalog.as_view()),
url(r'expo/(?P<params>.*)/statistic/$', ExpositionStatistic.as_view()), # city catalog
url(r'expo/(?P<params>.*)/price/$', ExpositionPrice.as_view()), url(r'expo/city/$', ExpositionByCity.as_view()),
url(r'expo/(?P<params>.*)/program/$', ExpositionProgramme.as_view()), url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view()),
# url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view()),
url(r'expo/(?P<params>.*)/visitors/$', ExpositionVisitors.as_view()), url(r'expo/city/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoCityCatalog.as_view()),
url(r'expo/(?P<params>.*)/members/$', ExpositionMembers.as_view()), url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoCityCatalog.as_view()),
url(r'expo/(?P<params>.*)/$', ExpositionView.as_view()), url(r'expo/city/(?P<slug>.*)/(?P<year>\d+)/$', ExpoCityCatalog.as_view()),
url(r'expo/$', ExpositionView.as_view()), url(r'expo/city/(?P<slug>.*)/$', ExpoCityCatalog.as_view()),
# # theme catalog
url(r'expo/theme/$', ExpositionByTheme.as_view()),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view()),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view()),
url(r'expo/theme/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoThemeCatalog.as_view()),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoThemeCatalog.as_view()),
url(r'expo/theme/(?P<slug>.*)/(?P<year>\d+)/$', ExpoThemeCatalog.as_view()),
url(r'expo/theme/(?P<slug>.*)/$', ExpoThemeCatalog.as_view()),
# tag catalog
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view()),
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view()),
url(r'expo/tag/(?P<slug>.*)/page/(?P<page>\d+)/$', ExpoTagCatalog.as_view()),
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/(?P<month>.*)/$', ExpoTagCatalog.as_view()),
url(r'expo/tag/(?P<slug>.*)/(?P<year>\d+)/$', ExpoTagCatalog.as_view()),
url(r'expo/tag/(?P<slug>.*)/$', ExpoTagCatalog.as_view()),
# expo additional pages
url(r'expo/(?P<slug>.*)/statistic/$', ExpositionStatistic.as_view()),
url(r'expo/(?P<slug>.*)/price/$', ExpositionPrice.as_view()),
url(r'expo/(?P<slug>.*)/program/$', ExpositionProgramme.as_view()),
url(r'expo/(?P<slug>.*)/visitors/page/(?P<page>\d+)/$', ExpoVisitors.as_view()),
url(r'expo/(?P<slug>.*)/visitors/$', ExpoVisitors.as_view()),
url(r'expo/(?P<slug>.*)/members/page/(?P<page>\d+)/$', ExpoMembers.as_view()),
url(r'expo/(?P<slug>.*)/members/$', ExpoMembers.as_view()),
url(r'expo/(?P<slug>.*)/service/(?P<service_url>.*)/', ExpositionServiceView.as_view()),
# expo list
url(r'expo/(?P<year>\d+)/(?P<month>.*)/page/(?P<page>\d+)/$', ExpoList.as_view()),
url(r'expo/(?P<year>\d+)/page/(?P<page>\d+)/$', ExpoList.as_view()),
url(r'expo/(?P<year>\d+)/(?P<month>.*)/$', ExpoList.as_view()),
url(r'expo/(?P<year>\d+)/$', ExpoList.as_view()),
url(r'expo/page/(?P<page>\d+)/$', ExpoList.as_view()),
# expo page
url(r'expo/(?P<slug>.*)/$', ExpoDetail.as_view()),# event
url(r'expo/$', ExpoList.as_view()),
url(r'expo/add-note/(?P<slug>.*)/$', 'exposition.views.add_note'),
#url(r'expo/(?P<slug>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()),
#url(r'expo/(?P<params>.*)/service/(?P<url>.*)/$', ExpositionServiceView.as_view()),
#url(r'expo/(?P<params>.*)/statistic/$', ExpositionStatistic.as_view()),
url(r'exposition-add-calendar/(?P<id>\d+)/$', 'exposition.views.exposition_add_calendar'), url(r'exposition-add-calendar/(?P<id>\d+)/$', 'exposition.views.exposition_add_calendar'),
url(r'exposition-visit/(?P<id>\d+)/$', 'exposition.views.exposition_visit'), url(r'exposition-visit/(?P<id>\d+)/$', 'exposition.views.exposition_visit'),

@ -1,54 +1,63 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import json
import datetime
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.contrib import messages from django.contrib import messages
#models from django.contrib.contenttypes.models import ContentType
from models import Exposition from django.conf import settings
from functions.custom_views import ExpoListView, ExpoMixin, EventDetail, single_page_filter from django.views.generic import ListView, DetailView
from django.views.generic import ListView, DetailView, FormView from django.utils.translation import ugettext as _
from haystack.query import EmptySearchQuerySet
from functions.search_forms import ExpositionSearchForm
from service.views import order_forms
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.http import Http404 from django.http import Http404
from django.utils import translation from django.utils import translation
# #models
from models import Exposition
from service.views import order_forms
from service.models import Service from service.models import Service
from country.models import Country from country.models import Country
from city.models import City from city.models import City
from company.models import Company
from theme.models import Theme, Tag from theme.models import Theme, Tag
import json from note.models import Note
from django.utils.translation import ugettext as _ from functions.custom_views import ExpoSearchView
from functions.search_forms import ExpositionSearchForm
from functions.custom_views import ExpoSearchView
class ExpositionByCountry(ListView):
model = Country
template_name = 'exposition/exposition_by_country.html'
def get_queryset(self):
lang = translation.get_language()
return self.model.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=lang)\
.order_by('translations__name').distinct()
class ExpositionBy(ListView): class ExpositionBy(ListView):
template_name = 'exposition/exposition_by.html' template_name = 'exposition/exposition_by.html'
title1 = '' title1 = ''
title2 = '' title2 = ''
""" """
abstact class abstact class
""" """
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExpositionBy, self).get_context_data(**kwargs) context = super(ExpositionBy, self).get_context_data(**kwargs)
context.update({'title1': self.title1, 'title2': self.title2}) context.update({'title1': self.title1, 'title2': self.title2, 'catalog': self.catalog})
return context return context
class ExpositionByCountry(ExpositionBy):
model = Country
title1 = _(u'По странам')
title2 = _(u'Выставки мира по странам')
catalog = 'country/'
def get_queryset(self):
lang = translation.get_language()
return self.model.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=lang)\
.order_by('translations__name').distinct()
class ExpositionByTheme(ExpositionBy): class ExpositionByTheme(ExpositionBy):
model = Theme model = Theme
title1 = _(u'По тематикам') title1 = _(u'По тематикам')
title2 = _(u'Выставки мира по тематикам') title2 = _(u'Выставки мира по тематикам')
catalog = 'theme/'
def get_queryset(self): def get_queryset(self):
lang = translation.get_language() lang = translation.get_language()
@ -57,12 +66,11 @@ class ExpositionByTheme(ExpositionBy):
.order_by('translations__name').distinct() .order_by('translations__name').distinct()
class ExpositionByCity(ExpositionBy): class ExpositionByCity(ExpositionBy):
model = City model = City
title1 = _(u'По городам') title1 = _(u'По городам')
title2 = _(u'Выставки мира по городам') title2 = _(u'Выставки мира по городам')
catalog = 'city/'
def get_queryset(self): def get_queryset(self):
lang = translation.get_language() lang = translation.get_language()
@ -70,259 +78,346 @@ class ExpositionByCity(ExpositionBy):
.filter(exposition_city__city__isnull=False, translations__language_code=lang)\ .filter(exposition_city__city__isnull=False, translations__language_code=lang)\
.order_by('translations__name').distinct() .order_by('translations__name').distinct()
class ExpositionServiceView(FormView, ExpoMixin):
params = None class ExpositionSearchView(ExpoSearchView):
#paginate_by = 10
template_name = 'exposition/search.html'
search_form = ExpositionSearchForm search_form = ExpositionSearchForm
model = Exposition model = Exposition
obj = None
service = None
def get_form_class(self): def exposition_add_calendar(request, id):
url = self.kwargs.get('url') args = {'success': False}
form = order_forms.get(url) user = request.user
if not form:
raise Http404
service = get_object_or_404(Service, url=url) if user.is_authenticated():
self.service = service exp = Exposition.objects.safe_get(id=id)
self.template_name = service.template if exp in user.calendar.get_expos():
params = self.get_params() user.calendar.expositions.remove(exp)
for param in params: args['in'] = False
else:
user.calendar.expositions.add(exp)
args['in'] = True
args['success'] = True
else:
args['not_authorized'] = True
args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json')
if param.get('type') == 'country': def exposition_visit(request, id):
country = Country.objects.safe_get(url=param.get('url')) args = {'success': False}
if country: user = request.user
param['name'] = country.name if user.is_authenticated():
exp = Exposition.objects.safe_get(id=id)
if user in exp.users.all():
exp.users.remove(user)
args['in'] = False
else:
exp.users.add(user)
args['in'] = True
if param.get('type') == 'city': args['success'] = True
city = City.objects.safe_get(url=param.get('url')) """
if city: if exp:
param['name'] = city.name exp.users.add(user)
args['success'] = True
"""
if param.get('type') == 'theme': else:
theme = Theme.objects.safe_get(url=param.get('url')) args['not_authorized'] = True
if theme: args['success'] = True
param['name'] = theme.name
if param.get('type') == 'tag': return HttpResponse(json.dumps(args), content_type='application/json')
tag = Tag.objects.safe_get(url=param.get('url')) #------------------------------------------------------------------------------
if tag:
param['name'] = tag.name
if param.get('type') == 'year':
param['name'] = param.get('url')
if param.get('type') == 'month': class ExpoDetail(DetailView):
monthes = {'jan': 1, 'feb': 2, 'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, model = Exposition
'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12} slug_field = 'url'
template_name = 'client/exposition/exposition_detail.html'
param['name'] = param.get('url') class ExpositionProgramme(DetailView):
model = Exposition
slug_field = 'url'
template_name = 'client/exposition/programm.html'
if param.get('type') == 'member' and self.model != Company:
param['name'] = param.get('url')
company = Company.objects.safe_get(url=param.get('url'))
if company:
param['name'] = company.name
if param.get('type') == single_page_filter.get(self.model): class ExpositionPrice(DetailView):
try: model = Exposition
self.obj = self.model.objects.get(url=param.get('url')) slug_field = 'url'
template_name = 'client/exposition/price.html'
except self.model.DoesNotExist:
raise Http404
param['name'] = self.obj.name class ExpositionStatistic(DetailView):
model = Exposition
slug_field = 'url'
template_name = 'client/exposition/statistic.html'
params.append({'type':'service', 'name':service.name}) from django.views.generic.edit import FormMixin, ModelFormMixin
self.params = params class ExpositionServiceView(FormMixin, DetailView):
return form model = Exposition
slug_field = 'url'
service = None
def post(self, request, *args, **kwargs):
self.object = self.get_object()
service_url = self.kwargs.get('service_url')
service = get_object_or_404(Service, url=service_url)
service_form = order_forms.get(service_url)
self.form_class = service_form
form = self.get_form(service_form)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExpositionServiceView, self).get_context_data(**kwargs) context = super(ExpositionServiceView, self).get_context_data(**kwargs)
context['search_form'] = ExpositionSearchForm() service_url = self.kwargs.get('service_url')
context['search_action'] = '/expositions/search/' service = get_object_or_404(Service, url=service_url)
context['event'] = self.obj self.service = service
context['service'] = self.service self.template_name = service.template
context['filter'] = self.params form = order_forms.get(service_url)
self.form_class = form
if not form:
raise Http404
context['form'] = self.get_form(self.form_class)
context['service'] = service
context['object'] = self.get_object()
return context return context
def form_valid(self, form): def form_valid(self, form):
form.save() order = form.save(commit=False)
order.exposition = self.object
order.save()
messages.success(self.request, _(u'Ваш запрос был успешно отправлен')) messages.success(self.request, _(u'Ваш запрос был успешно отправлен'))
return HttpResponseRedirect(self.request.path) return HttpResponseRedirect(self.request.path)
#def form_invalid(self, form): def get_initial(self):
# return HttpResponse(form.errors) """
Returns the initial data to use for forms on this view.
"""
if self.request.user.is_authenticated():
user = self.request.user
initial = {'person_inf': user.get_full_name(),
'person': user.email,
'country': user.profile.country.name if user.profile.country else '',
'city':user.profile.city.name if user.profile.city else '',
'phone': user.profile.phone if user.profile.phone else ''}
class ExpositionSearchView(ListView): return initial
paginate_by = 10 else:
template_name = 'exposition/search.html' return self.initial.copy()
search_form = ExpositionSearchForm
class ExpoList(ListView):
model = Exposition model = Exposition
paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/exposition/exposition_list.html'
search_form = ExpositionSearchForm
catalog_url = '/expo/'
year = None
month = None
def get_queryset(self): def get_queryset(self):
if self.request.user.is_staff:
if self.request.GET: now = datetime.datetime.now().date()
form = self.search_form(self.request.GET) qs = self.model.objects.filter(data_begin__gte=now).order_by('data_begin')
if form.is_valid():
return form.search()
else:
return EmptySearchQuerySet()
else: else:
return EmptySearchQuerySet() qs = self.model.enable.all()
def get_context_data(self, **kwargs): year = self.kwargs.get('year')
context = super(ExpositionSearchView, self).get_context_data(**kwargs) if year:
qs = qs.filter(data_begin__year=year)
# info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/'%(self.catalog_url, year)}
context['search_form'] = ExpositionSearchForm(self.request.GET) month = self.kwargs.get('month')
queries = self.request.GET.copy() if month and MONTHES.get(month):
if queries.has_key('page'): qs = qs.filter(data_begin__month=MONTHES[month]['value'])
del queries['page'] self.month = {'text': MONTHES[month]['name'], 'link': '%s%s/%s/'%(self.catalog_url, year, month)}
context['queries'] = queries return qs
context['search_action'] = '/expo/search/'
def get_context_data(self, **kwargs):
context = super(ExpoList, self).get_context_data(**kwargs)
context['month'] = self.month
context['catalog_url'] = self.catalog_url
context['search_form'] = self.search_form
context['year'] = self.year
context['month'] = self.month
return context return context
MONTHES = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
class ExpositionView(ExpoListView): class ExpoCatalog(ListView):
model = Exposition model = Exposition
template_name = 'event_catalog.html' paginate_by = settings.CLIENT_PAGINATION
template_name = 'exposition/catalog.html'
search_form = ExpositionSearchForm search_form = ExpositionSearchForm
order = 'data_begin' filter_object = None
year = None
month = None
def get_filtered_qs(self):
# diferent for views
pass
def get_queryset(self):
qs = self.get_filtered_qs()
year = self.kwargs.get('year')
if year:
qs = qs.filter(data_begin__year=year)
# info for breadscrumbs
self.year = {'text': year, 'link': '%s%s/%s/'%(self.catalog_url, self.filter_object.url, year)}
month = self.kwargs.get('month')
monthes = {'jan': {'value': 1, 'name': _(u'Январь')}, 'feb': {'value': 2, 'name': _(u'Февраль')},
'mar': {'value': 3, 'name': _(u'Март')}, 'apr': {'value': 4, 'name': _(u'Апрель')},
'may': {'value': 5, 'name': _(u'Май')}, 'jun': {'value': 6, 'name': _(u'Июнь')},
'jul': {'value': 7, 'name': _(u'Июль')}, 'aug': {'value': 8, 'name': _(u'Август')},
'sep': {'value': 9, 'name': _(u'Сентябрь')}, 'oct': {'value': 10, 'name': _(u'Октябрь')},
'nov': {'value': 11, 'name': _(u'Ноябрь')}, 'dec': {'value': 12, 'name': _(u'Декабрь')}}
if month and monthes.get(month):
qs = qs.filter(data_begin__month=monthes[month]['value'])
self.month = {'text': monthes[month]['name'], 'link': '%s%s/%s/%s/'%(self.catalog_url, self.filter_object.url, year, month)}
return qs.order_by('data_begin')
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(ExpositionView, self).get_context_data(**kwargs) context = super(ExpoCatalog, self).get_context_data(**kwargs)
context['search_action'] = '/expositions/search/' context['search_form'] = self.search_form
context['filter_object'] = self.filter_object
context['year'] = self.year
context['month'] = self.month
context['catalog_url'] = self.catalog_url
return context return context
class ExpositionVisitors(ExpositionView): class ExpoCountryCatalog(ExpoCatalog):
catalog_url = '/expo/country/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
country = get_object_or_404(Country, url=slug)
self.filter_object = country
qs = self.model.enable.filter(country=country)
return qs
class ExpoCityCatalog(ExpoCatalog):
catalog_url = '/expo/city/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
city = get_object_or_404(City, url=slug)
qs = self.model.enable.filter(city=city)
self.filter_object = city
return qs
class ExpoThemeCatalog(ExpoCatalog):
catalog_url = '/expo/theme/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
theme = get_object_or_404(Theme, url=slug)
qs = self.model.enable.filter(theme=theme)
self.filter_object = theme
return qs
class ExpoTagCatalog(ExpoCatalog):
catalog_url = '/expo/tag/'
def get_filtered_qs(self):
#this method used in parent get_queryset
slug = self.kwargs.get('slug')
tag = get_object_or_404(Tag, url=slug)
qs = self.model.enable.filter(tag=tag)
self.filter_object = tag
return qs
class ExpoVisitors(ListView):
paginate_by = settings.CLIENT_PAGINATION
model = Exposition model = Exposition
template_name = 'event_visitors.html' #template_name = 'event_visitors.html'
def get_queryset(self): template_name = 'client/exposition/visitors.html'
obj = None
search_form = ExpositionSearchForm
params = self.get_params() def get_queryset(self):
for param in params: slug = self.kwargs.get('slug')
if param.get('type') == 'event': exposition = get_object_or_404(self.model, url=slug)
exp = Exposition.objects.safe_get(url=param.get('url')) self.obj = exposition
#query = exp.users return exposition.users.all()
param['name'] = exp.name
params.append({'type':'visitors', 'name':_(u'Посетители')})
self.params = params def get_context_data(self, **kwargs):
return exp.users.all() context = super(ExpoVisitors, self).get_context_data(**kwargs)
context['object'] = self.obj
context['search_form'] = self.search_form
return context
class ExpositionMembers(ExpoListView): class ExpoMembers(ListView):
paginate_by = settings.CLIENT_PAGINATION
model = Exposition model = Exposition
template_name = 'event_members.html' #template_name = 'event_visitors.html'
def get_queryset(self): template_name = 'client/exposition/members.html'
params = self.get_params() obj = None
for param in params: search_form = ExpositionSearchForm
if param.get('type') == 'event':
exp = Exposition.objects.safe_get(url=param.get('url'))
param['name'] = exp.name
#query = exp.users
params.append({'type':'members', 'name':_(u'Участники')})
self.params = params
return exp.company.all()
class ExpositionStatistic(ExpoListView):
model = Exposition
template_name = 'exposition_statistic.html'
def get_queryset(self):
params = self.get_params()
for param in params:
if param.get('type') == 'event':
exp = Exposition.objects.filter(url=param.get('url'))
param['name'] = exp[0].name
#query = exp.users
self.single_page = True
params.append({'type':'statistic', 'name':_(u'Статистика')})
self.params = params
return exp
class ExpositionProgramme(ExpoListView):
model = Exposition
template_name = 'exposition_programm.html'
def get_queryset(self):
params = self.get_params()
for param in params:
if param.get('type') == 'event':
exp = Exposition.objects.filter(url=param.get('url'))
param['name'] = exp[0].name
#query = exp.users
self.single_page = True
params.append({'type':'programme', 'name':_(u'Программа')})
self.params = params
return exp
class ExpositionPrice(ExpoListView):
model = Exposition
template_name = 'exposition_price.html'
def get_queryset(self):
params = self.get_params()
for param in params:
if param.get('type') == 'event':
exp = Exposition.objects.filter(url=param.get('url'))
param['name'] = exp[0].name
#query = exp.users
self.single_page = True
params.append({'type':'price', 'name':_(u'Стоимость посещения и участия')})
self.params = params
return exp
def get_queryset(self):
slug = self.kwargs.get('slug')
exposition = get_object_or_404(self.model, url=slug)
self.obj = exposition
return exposition.company.all()
def get_context_data(self, **kwargs):
context = super(ExpoMembers, self).get_context_data(**kwargs)
context['object'] = self.obj
context['search_form'] = self.search_form
return context
def exposition_add_calendar(request, id): def add_note(request, slug):
args = {'success': False} args = {'success': False}
user = request.user
if user.is_authenticated():
exp = Exposition.objects.safe_get(id=id)
if exp in user.calendar.expositions.all():
user.calendar.expositions.remove(exp)
args['in'] = False
else:
user.calendar.expositions.add(exp)
args['in'] = True
args['success'] = True
else:
args['not_authorized'] = True
args['success'] = True
return HttpResponse(json.dumps(args), content_type='application/json') if request.GET:
text = request.GET['note_text']
try:
e = Exposition.objects.get(url=slug)
except Exposition.DoesNotExist:
raise Http404
def exposition_visit(request, id): ct = ContentType.objects.get_for_model(e)
args = {'success': False} object_id = e.id
user = request.user user = request.user
if user.is_authenticated(): if Note.objects.filter(user=user, content_type=ct, object_id=object_id).exists():
exp = Exposition.objects.safe_get(id=id) Note.objects.filter(user=user, content_type=ct, object_id=object_id).update(text=text)
if user in exp.users.all():
exp.users.remove(user)
args['in'] = False
else: else:
exp.users.add(user) Note.objects.create(content_type=ct, object_id=object_id, user=user, text=text)
args['in'] = True
user.calendar.expositions.add(e)
args['success'] = True
"""
if exp:
exp.users.add(user)
args['success'] = True
"""
else:
args['not_authorized'] = True
args['success'] = True args['success'] = True
args['text'] = text
return HttpResponse(json.dumps(args), content_type='application/json') return HttpResponse(json.dumps(args), content_type='application/json')

@ -12,6 +12,73 @@ from functions.translate import populate, fill_trans_fields_all
from PIL import Image from PIL import Image
import pytils, re import pytils, re
class FileForm(forms.Form):
file_path = forms.FileField(label='Выберите файл')
model = forms.CharField(required=False, widget=forms.HiddenInput())
purposes = [('scheme teritory','Схема територии'),('preview','Превью')]
purpose = forms.ChoiceField(label='Назаначение', choices=purposes)
def __init__(self, *args, **kwargs):
"""
creates dynamical translated fields
"""
super(FileForm, self).__init__(*args, **kwargs)
# creates translated form fields, example: name_ru, name_en
# len(10) is a hack for detect if settings.LANGUAGES is not configured it return all langs
if len(settings.LANGUAGES) in range(10):
for lid, (code, name) in enumerate(settings.LANGUAGES):
# using enumerate for detect iteration number
# first iteration is a default lang so it required fields
required = True if lid == 0 else False
self.fields['file_name_%s'%code] = forms.CharField(label='Имя файла',required=False, widget=forms.TextInput(attrs={'placeholder': 'Имя'}))
self.fields['description_%s'%code] = forms.CharField(label='Описание', required=False, widget=forms.Textarea())
def save(self, request, obj=None):
"""
"""
data = self.cleaned_data
if not obj:
return None
else:
file_obj = FileModel()
file_obj.content_type = ContentType.objects.get_for_model(obj)
file_obj.object_id = getattr(obj, 'id')
#change all symbols than are not letter or number to '_'from file name
# and translit name
file_name = u'%s'%request['file_path'].name
file_name = pytils.translit.translify(file_name)
file_name = re.sub('[^\w\-_\.]', '_', file_name)
file_name = re.sub('_+', '_', file_name)
#file_name = re.sub('_+', '_', re.sub('[^\w\-_\. ]', '_', pytils.translit.translify(u'%s'%request['file_path'].name)))
request['file_path'].name = file_name
#-------
file_obj.file_path = request['file_path']
file_obj.purpose = data['purpose']
#type of file
type = str(data['file_path']).split('.')[-1]
#if type is image save fields with image size
if type.upper() in IMG_TYPES:
f = Image.open(data['file_path'])
file_obj.img_width, file_obj.img_height = f.size
#saves file_type
try:
file_obj.file_type = type
file_obj.save()
except:
file_obj.file_type = 'OTHER'
file_obj.save()
#fills and saves translated fields
fill_trans_fields_all(FileModel, file_obj, data)
return file_obj
class FileModelForm(forms.Form): class FileModelForm(forms.Form):
""" """
Create FileModel form Create FileModel form

@ -23,7 +23,9 @@ class AdminFilterForm(forms.Form):
class for filtering lists in admin panel class for filtering lists in admin panel
""" """
model = None # which models work with model = None # which models work with
name = forms.CharField(label=_(u'Имя'), required=False) exact_name = forms.CharField(label=_(u'Название'), required=False)
name = forms.CharField(label=_(u'Часть названия'), required=False)
def filter(self): def filter(self):
""" """
@ -32,11 +34,16 @@ class AdminFilterForm(forms.Form):
form must be cleaned before calling this method form must be cleaned before calling this method
""" """
model = self.model
data = self.cleaned_data data = self.cleaned_data
name = data['name'] name = data['name']
model = self.model exact_name = data['exact_name']
if exact_name:
qs = model.objects.filter(translations__name=name).distinct()
return qs
qs = model.objects.all() qs = model.objects.all()
if name: if name:
qs = qs.filter(translations__name__contains=name) qs = qs.filter(translations__name__contains=name).distinct()
return qs return qs

@ -10,11 +10,15 @@ class AdminView(FormView):
def set_obj(self): def set_obj(self):
url = self.kwargs.get('url') url = self.kwargs.get('url')
#
#rewrwe
if url: if url:
obj = get_object_or_404(self.model, url=url) try:
self.obj = obj obj = self.model.objects.get(url=url)
self.obj = obj
except:
raise Http404
pass
# obj = get_object_or_404(self.model, url=url)
return obj return obj
slug = self.kwargs.get('slug') slug = self.kwargs.get('slug')
if slug: if slug:
@ -117,7 +121,7 @@ class AdminListView(FormView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = super(AdminListView, self).get_context_data(**kwargs) context = super(AdminListView, self).get_context_data(**kwargs)
qs = self.model.objects.all() qs = self.model.objects.language().all().order_by('name')
result = paginate_results(qs, page=self.request.GET.get('page')) result = paginate_results(qs, page=self.request.GET.get('page'))
context['object_list'] = result context['object_list'] = result
return context return context

@ -221,7 +221,8 @@ single_page_filter = {Exposition:'event', Conference:'event', Seminar:'event', W
from meta.models import MetaSetting
from meta.views import Meta
class ExpoListView(ExpoMixin, ListView): class ExpoListView(ExpoMixin, ListView):
""" """
""" """
@ -299,6 +300,13 @@ class ExpoListView(ExpoMixin, ListView):
context['filter'] = self.params context['filter'] = self.params
context['single_page'] = self.single_page context['single_page'] = self.single_page
context['search_form'] = self.search_form context['search_form'] = self.search_form
if self.single_page:
s = MetaSetting.objects.get(name='expo')
obj = context['object_list'][0]
params = s.generate_meta(obj)
m = Meta(**params)
context['meta'] = m
return context return context
from country.models import Country from country.models import Country
@ -307,3 +315,41 @@ class EventDetail(ExpoMixin, DetailView):
def get_object(self, queryset=None): def get_object(self, queryset=None):
obj = Country.objects.filter()[0] obj = Country.objects.filter()[0]
return obj return obj
from haystack.query import EmptySearchQuerySet
class ExpoSearchView(ListView):
paginate_by = 10
template_name = None
search_form = None
model = None
def get_queryset(self):
if self.request.GET:
form = self.search_form(self.request.GET)
if form.is_valid():
return form.search()
else:
return EmptySearchQuerySet()
else:
return EmptySearchQuerySet()
def get_context_data(self, **kwargs):
context = super(ExpoSearchView, self).get_context_data(**kwargs)
form = self.search_form(self.request.GET)
if self.request.GET:
if form.is_valid():
form.data_with_parents = form.get_form_data()
context['search_form'] = form
queries = self.request.GET.copy()
if queries.has_key('page'):
del queries['page']
context['queries'] = queries
return context

@ -15,7 +15,12 @@ def is_positive_integer(data,
else: else:
raise ValidationError(msg) raise ValidationError(msg)
from slugify import slugify
def translit_with_separator(string, separator='-'): def translit_with_separator(string, separator='-'):
return slugify(string, to_lower=True)
""" """
Trsanslit string and replace "bad" symbols for separator Trsanslit string and replace "bad" symbols for separator

@ -4,9 +4,9 @@ from service.models import Service
class ExpoMixin(object): class ExpoMixin(object):
def get_index_text(self): # def get_index_text(self):
names = [tr.name for tr in self.translations.all()] # names = [tr.name for tr in self.translations.all()]
return names # return names
def get_logo(self): def get_logo(self):
@ -29,9 +29,12 @@ class ExpoMixin(object):
class EventMixin(object): class EventMixin(object):
def get_permanent_url(self): def get_permanent_url(self):
url = '%sevent-%s'%(self.get_catalog_url(), self.url) url = '%s%s/'%(self.get_catalog_url(), self.url)
return url return url
def get_logo(self): def get_logo(self):
return self.logo return self.logo
""" """
@ -75,9 +78,8 @@ class EventMixin(object):
def get_services(self): def get_services(self):
ids = [item for item, bool in self.country.services if bool==True] ids = [item for item, bool in self.country.services if bool==True]
return [Service.objects.get(url=id) for id in ids] ##sasa
return list(Service.objects.language().filter(url__in=ids).order_by('sort'))
def duration_days(self, month=None): def duration_days(self, month=None):
if not month: if not month:

@ -1,10 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import pytils import pytils
import ast
import json
from django import forms from django import forms
from django.db.models import Q from django.db.models import Q
from django.utils import translation
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from haystack.query import EmptySearchQuerySet, SearchQuerySet from haystack.query import EmptySearchQuerySet, SearchQuerySet
from country.models import Area
from theme.models import Theme
from exposition.models import Exposition from exposition.models import Exposition
from conference.models import Conference from conference.models import Conference
from seminar.models import Seminar from seminar.models import Seminar
@ -13,127 +17,86 @@ from company.models import Company
from theme.models import Theme, Tag from theme.models import Theme, Tag
from country.models import Country from country.models import Country
from city.models import City from city.models import City
import ast from place_exposition.models import PlaceExposition
from place_conference.models import PlaceConference
class AbstactSearchForm(forms.Form): class AbstactSearchForm(forms.Form):
q = forms.CharField(label=_(u'Поиск'), required=False) q = forms.CharField(label=_(u'Я ищу'), required=False)
w = forms.CharField(label=_(u'Где'), required=False) w = forms.CharField(label=_(u'Где'), required=False)
models = None
data_with_parents = None
def get_form_data(self):
data = self.cleaned_data
area = data.get('area')
co = data.get('co')
ci = data.get('ci')
th = data.get('th')
tg = data.get('tg')
if area:
ar = Area.objects.filter(id__in=area)
areas = [{'name':'area', 'id':item.id, 'parent':None, 'text':item.name} for item in ar]
else:
areas = []
class CompanySearchForm(AbstactSearchForm):
th = forms.MultipleChoiceField(label=_(u'Тематика'), required=False,
choices=[(theme.id, theme.name) for theme in Theme.objects.all()])
tg = forms.MultipleChoiceField(label=_(u'Теги'), required=False,
choices=[(tag.id, tag.name) for tag in Tag.objects.all()])
c = forms.CharField(label=_(u'Страна'), required=False, widget=forms.SelectMultiple())
city = forms.CharField(label=_(u'город'), required=False, widget=forms.SelectMultiple())
def clean_city(self):
city = self.cleaned_data.get('city')
if city:
res = ast.literal_eval(city)
return res
return city
def clean_c(self):
country = self.cleaned_data.get('c')
if country:
res = ast.literal_eval(country)
return res
return country
def search(self):
q = self.cleaned_data.get('q')
w = self.cleaned_data.get('w')
th = self.cleaned_data.get('th')
tg = self.cleaned_data.get('tg')
c = self.cleaned_data.get('c')
city = self.cleaned_data.get('city')
sqs = SearchQuerySet().models(Company)
if q:
sqs = sqs.auto_query(q)
if w:
sqs = sqs.filter(where__contains=w)
if th: if th:
themes = Theme.objects.filter(id__in=th)
ths = [{'name':'th', 'id':item.id, 'parent':None, 'text':item.name} for item in themes]
else:
ths = []
sqs = sqs.filter(theme__in=th)
if tg: if tg:
sqs = sqs.filter(tag__in=tg) tgs = []
if c: for item in tg:
sqs = sqs.filter(country__in=c) try:
if city: tag = Tag.objects.language().get(id=item)
sqs = sqs.filter(country__in=c) tgs.append({'name':'th', 'id':tag.theme_id, 'text': tag.theme.name, 'children':{
'id': item, 'name':'tg', 'text': tag.name
}
})
return sqs except:
continue
else:
from country.models import Area tgs = []
from theme.models import Theme
from django.utils import translation
class ExpositionSearchForm(forms.Form):
search_url = '/expo/search/'
q = forms.CharField(label=_(u'Поиск'), required=False)
w = forms.CharField(label=_(u'Где'), required=False)
th = forms.MultipleChoiceField(label=_(u'Тематика'), choices=[(item.id, item.name) for item in Theme.objects.all()],
required=False, widget=forms.CheckboxSelectMultiple())
tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()],
required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
fr = forms.DateField(required=False,
widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateFrom',
'placeholder': _(u'дд.мм.гггг')}))
to = forms.DateField(required=False,
widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateTo',
'placeholder': _(u'дд.мм.гггг')}))
def __init__(self, *args, **kwargs):
super(ExpositionSearchForm, self).__init__(*args, **kwargs)
self.theme_classes = {item.id:item.generate_search_class() for item in Theme.objects.all()}
"""
theme_with_tags = {}
for tag in list(Tag.objects.language().filter()):
if tag.theme_id in theme_with_tags:
theme_with_tags[tag.theme_id].append({'name': tag.name, 'id':tag.id})
else:
theme_with_tags[tag.theme_id] = [{'name': tag.name, 'id':tag.id}]
#dsds if co:
self.theme_with_tags = theme_with_tags cos = []
""" for item in co:
try:
country = Country.objects.get(id=item)
cos.append({'name':'area', 'id':country.area_id, 'text': country.area.name, 'children':{
'id': item, 'name':'co', 'text': country.name
}
})
except:
continue
else:
cos = []
if ci:
cis = []
for item in ci:
try:
city = City.objects.language().get(id=item)
cis.append({'name':'area', 'id': city.country.area_id, 'text': city.country.area.name, 'children':{
'id': city.country_id, 'name':'co', 'text': city.country.name, 'children':{
'name':'ci', 'id':item, 'text':city.name
}
}
})
except:
continue
else:
cis = []
finale_list = areas + cos + cis + ths + tgs
result = {'inputs': finale_list}
result = json.dumps(result)
return result
def get_places_display(self): def get_places_display(self):
@ -192,13 +155,117 @@ class ExpositionSearchForm(forms.Form):
res = ast.literal_eval(tg) res = ast.literal_eval(tg)
return res return res
return tg return tg
"""
def clean_co(self):
co = self.cleaned_data.get('co')
if co:
res = ast.literal_eval(co)
return res
return co
"""
def search(self):
if not self.is_valid():
return EmptySearchQuerySet()
q = self.cleaned_data.get('q')
w = self.cleaned_data.get('w')
fr = self.cleaned_data.get('fr')
to = self.cleaned_data.get('to')
th = self.cleaned_data.get('th')
tg = self.cleaned_data.get('tg')
co = self.cleaned_data.get('co')
ci = self.cleaned_data.get('ci')
area = self.cleaned_data.get('area')
sqs = SearchQuerySet().models(*self.models).all()
if q:
sqs = sqs.autocomplete(content_auto=q)
if w:
sqs = sqs.filter(where__contains=w)
if fr:
sqs = sqs.filter(data_begin__gte=fr)
if to:
sqs = sqs.filter(data_begin__lte=to)
if th:
sqs = sqs.filter(theme__in=th)
if tg:
sqs = sqs.filter(tag__in=tg)
place_filter = None
if area:
if place_filter:
place_filter = place_filter | Q(area_id__in=area)
else:
place_filter = Q(area_id__in=area)
#sqs = sqs.filter(area_id__in=area)
if co:
if place_filter:
place_filter = place_filter | Q(country_id__in=co)
else:
place_filter = Q(country_id__in=co)
#sqs = sqs.filter(country_id__in=co)
if ci:
if place_filter:
place_filter = place_filter | Q(city_id__in=ci)
else:
place_filter = Q(city_id__in=ci)
#sqs = sqs.filter(city_id__in=ci)
if place_filter:
sqs = sqs.filter(place_filter)
return sqs#.order_by('data_begin')
class ExpositionSearchForm(AbstactSearchForm):
search_url = '/expo/search/'
autocomplete_url = '/search-form/autosearch/exposition/'
title = _(u'ПОИСК СОБЫТИЙ')
models = [Exposition]
th = forms.MultipleChoiceField(label=_(u'Тематика'), choices=[(item.id, item.name) for item in Theme.active.all()],
required=False, widget=forms.CheckboxSelectMultiple())
tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
#co = forms.CharField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple())
#tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()],
required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
fr = forms.DateField(required=False,
widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateFrom',
'placeholder': _(u'дд.мм.гггг')}))
to = forms.DateField(required=False,
widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateTo',
'placeholder': _(u'дд.мм.гггг')}))
def __init__(self, *args, **kwargs):
super(ExpositionSearchForm, self).__init__(*args, **kwargs)
self.theme_classes = {item.id:item.generate_search_class() for item in Theme.objects.all()}
def search(self): def search(self):
if not self.is_valid(): if not self.is_valid():
return EmptySearchQuerySet() return EmptySearchQuerySet()
data = self.cleaned_data
q = self.cleaned_data.get('q') q = self.cleaned_data.get('q')
w = self.cleaned_data.get('w') w = self.cleaned_data.get('w')
fr = self.cleaned_data.get('fr') fr = self.cleaned_data.get('fr')
@ -212,7 +279,7 @@ class ExpositionSearchForm(forms.Form):
sqs = SearchQuerySet().models(Exposition).all() sqs = SearchQuerySet().models(Exposition).all()
if q: if q:
sqs = sqs.auto_query(q) sqs = sqs.autocomplete(content_auto=q)
if w: if w:
sqs = sqs.filter(where__contains=w) sqs = sqs.filter(where__contains=w)
if fr: if fr:
@ -226,7 +293,6 @@ class ExpositionSearchForm(forms.Form):
place_filter = None place_filter = None
if area: if area:
if place_filter: if place_filter:
place_filter = place_filter | Q(area_id__in=area) place_filter = place_filter | Q(area_id__in=area)
@ -250,11 +316,93 @@ class ExpositionSearchForm(forms.Form):
if place_filter: if place_filter:
sqs = sqs.filter(place_filter) sqs = sqs.filter(place_filter)
return sqs.order_by('data_begin')
class PlaceSearchForm(AbstactSearchForm):
search_url = '/places/search/'
autocomplete_url = '/search-form/autosearch/place/'
title = _(u'ПОИСК МЕСТ')
models = [PlaceExposition, PlaceConference]
# place fields
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()],
required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
return sqs.order_by('data_begin') ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
#
place_type = forms.MultipleChoiceField(label=_(u'Тип'), required=False, choices=[])
def get_place_type_display(self):
return _(u'Не важно')
def search(self):
pass
class CompanySearchForm(AbstactSearchForm):
search_url = '/members/search/'
autocomplete_url = '/search-form/autosearch/company/'
title = _(u'ПОИСК УЧАСТНИКОВ')
models = [Company]
th = forms.MultipleChoiceField(label=_(u'Тематика'), choices=[(item.id, item.name) for item in Theme.objects.all()],
required=False, widget=forms.CheckboxSelectMultiple())
tg = forms.CharField(label=_(u'Теги'), required=False, widget=forms.CheckboxSelectMultiple())
area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.all_sorted()],
required=False, widget=forms.CheckboxSelectMultiple())
co = forms.MultipleChoiceField(label=_(u'Страна'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\
.filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
ci = forms.MultipleChoiceField(label=_(u'Город'), required=False, widget=forms.CheckboxSelectMultiple(),
choices=[(item.id, item.name) for item in City.objects.select_related('exposition_city')\
.filter(exposition_city__city__isnull=False, translations__language_code=translation.get_language())\
.order_by('translations__name').distinct()]
)
def __init__(self, *args, **kwargs):
super(CompanySearchForm, self).__init__(*args, **kwargs)
self.theme_classes = {item.id:item.generate_search_class() for item in Theme.objects.all()}
def search(self):
q = self.cleaned_data.get('q')
w = self.cleaned_data.get('w')
th = self.cleaned_data.get('th')
tg = self.cleaned_data.get('tg')
c = self.cleaned_data.get('c')
city = self.cleaned_data.get('city')
sqs = SearchQuerySet().models(Company)
if q:
sqs = sqs.auto_query(q)
if w:
sqs = sqs.filter(where__contains=w)
if th:
sqs = sqs.filter(theme__in=th)
if tg:
sqs = sqs.filter(tag__in=tg)
if c:
sqs = sqs.filter(country__in=c)
if city:
sqs = sqs.filter(country__in=c)
return sqs
class EventSearchForm(forms.Form): class EventSearchForm(forms.Form):
@ -284,4 +432,3 @@ class EventSearchForm(forms.Form):
sqs = sqs.filter(where__contains=w) sqs = sqs.filter(where__contains=w)
return sqs return sqs

@ -0,0 +1,65 @@
# -*- coding: utf-8 -*-
from haystack import indexes
class ExpoSearchMixin(object):
"""
"""
def prepare_where(self, obj):
if obj.country:
country = [tr.name for tr in obj.country.translations.all()]
else:
country = ''
if obj.city:
city = [tr.name for tr in obj.city.translations.all()]
else:
city = ''
return country + city
def prepare_content_auto(self, obj):
"""
object must have get_index_text method which generate text for searching
"""
return obj.get_index_text()
def prepare_area_id(self, obj):
if obj.country:
return obj.country.area.id
return None
def prepare_country_id(self, obj):
if obj.country:
return obj.country.id
return None
def prepare_city_id(self, obj):
if obj.city:
return obj.city.id
return None
def prepare_theme(self, obj):
return [th.id for th in obj.theme.filter()]
def prepare_tag(self, obj):
return [th.id for th in obj.tag.filter()]
def prepare_url(self, obj):
return obj.get_permanent_url()
def prepare_name_en(self, obj):
try:
return obj.translations.get(language_code = 'en').name
except:
return ''
def prepare_name_ru(self, obj):
try:
return obj.translations.get(language_code = 'ru').name
except:
return ''

@ -80,10 +80,16 @@ class ExportPlaceExposition(ExportView):
from exposition.models import Exposition
class ImportEvent(ImportView): class ImportEvent(FormView):
form_class = ImportEventForm form_class = ImportEventForm
success_url = '/admin/import-event' success_url = '/admin/import-event'
def form_valid(self, form):
result = form.save_file()
Exposition.imports.create_by_dict(result[0])
messages.success(self.request, 'Success')
return super(ImportView, self).form_valid(form)
class ImportTheme(ImportView): class ImportTheme(ImportView):
form_class = ImportThemeForm form_class = ImportThemeForm

@ -1,9 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from accounts.models import User # bad practice of importing, but to many functions must be imported
from country.models import Country from .utils import *
from city.models import City
from theme.models import Theme, Tag
from hvad.utils import get_translation_aware_manager
def get_bool(value): def get_bool(value):
if value: if value:
@ -15,20 +12,6 @@ def get_int(value):
return '' return ''
return value return value
from bitfield import BitHandler
from exposition.models import BIT_AUDIENCE
def get_audience(value):
if isinstance(value, BitHandler):
l = [k for k, v in value.iteritems() if v]
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if value == item1:
new_list.append(item2)
return ', '.join(new_list)
return
def get_theme(value): def get_theme(value):
objects = value.theme.all() objects = value.theme.all()
@ -46,7 +29,6 @@ def get_tag(tag, theme):
result += '['+','.join(tag_list)+']' result += '['+','.join(tag_list)+']'
return result return result
from place_exposition.models import EXPOSITION_TYPE
def get_place_type(value): def get_place_type(value):
for t in EXPOSITION_TYPE: for t in EXPOSITION_TYPE:
@ -136,120 +118,6 @@ field_settings = [
def to_int(val):
"""
Reverse function to get_int
return None if value isnt integer
"""
try:
return int(val)
except ValueError:
return None
def to_country(value):
try:
query = get_translation_aware_manager(Country)
country = query.filter(name=value)[0]
return country
except IndexError:
return None
def to_city(value, lang, country):
try:
# get city by name
#objects = get_translation_aware_manager(City)
# except IndexError if no found
city = City.objects.filter(translations__name=value, country=country)[0]
return city
except IndexError:
return None
from exposition.models import Exposition
def to_audience(value, model=Exposition):
if value:
l = value.split(', ')
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if value == item2:
new_list.append(item1)
if new_list:
return reduce(lambda x,y: x|y, (getattr(model.audience, item) for item in new_list))
return 0
def to_theme(obj, value):
if isinstance(value, float) or isinstance(value, int):
if (value - int(value) > 0):
value = str(value)
else:
value = str(int(value))
theme_ids = value.split('.')
else:
theme_ids = value.split(',')
theme_objects = []
for id in theme_ids:
try:
theme = Theme.objects.language('ru').get(id=int(id))
theme_objects.append(theme)
obj.theme.add(theme)
except Theme.DoesNotExist, ValueError:
pass
return theme_objects
"""
def to_tag(value, lang, themes):
if value == [""]:
return None
value = value.replace('[', '')
themes = themes.all()
# list tags by themes
value = value.split(']')
arr = []
for theme_number, theme in enumerate(themes):
for val in value[theme_number].split(','):
if val:
try:
tag = Tag.objects.language(lang).get(id=int(val), theme=theme)
arr.append(tag)
except Tag.DoesNotExist, ValueError:
pass
return arr
"""
def to_tag(obj,value):
if value == [""]:
return None
names = value.split(',')
tags = []
for name in names:
objects = get_translation_aware_manager(Tag)
tag = objects.filter(name=name)
#tag = Tag.objects.language('ru').filter(transations__name=name)
if tag:
tags.append(tag[0])
obj.tag.add(tag[0])
else:
continue
print(tags)
print(names)
return tags
def to_theme_type(st): def to_theme_type(st):
if not st: if not st:
return 15 return 15
@ -259,19 +127,9 @@ def to_theme_type(st):
flag = reduce(lambda x,y: x|y, (getattr(Theme.types, item) for item in types)) flag = reduce(lambda x,y: x|y, (getattr(Theme.types, item) for item in types))
return flag return flag
import time, xlrd
def to_date(value):
if not value:
return None
if isinstance(value, unicode) or isinstance(value, str):
t = time.strptime(value, "%d.%m.%Y")
if isinstance(value, float):
t = xlrd.xldate_as_tuple(value, 0)+(0,0,0)
return time.strftime("%Y-%m-%d", t)
def to_currency(value): def to_currency(value):
if value=='USD': if value=='USD':
@ -294,6 +152,7 @@ from django.core.validators import validate_email, URLValidator
def to_url(url): def to_url(url):
validate = URLValidator() validate = URLValidator()
try: try:
validate(url) validate(url)
except: except:
@ -388,7 +247,7 @@ def to_phone(value):
value = value.replace(elem, '') value = value.replace(elem, '')
value = to_int(value) value = to_int(value)
print(value)
return value return value
@ -465,52 +324,43 @@ place_exp_sett = {
u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool}, u'Мобильное приложение':{u'field': u'mobile_application', u'func': bool},
} }
from place_exposition.models import PlaceExposition
def to_place(value):
try:
place = PlaceExposition.objects.get(id=value)
return place
except:
return None
event_sett = { event_sett = {
u'ID':{u'field': u'id', u'func': to_int}, 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'name', u'func': unicode},
u'Краткое описание':{u'field': u'main_title', 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_begin', u'func': to_date},
u'Дата окончания:(YYYY-MM-DD)':{u'field': u'data_end', 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'country', u'func': to_country},
u'Город':{u'field': u'city', u'func': to_city, 'extra_values': 'country'}, u'Город':{u'field': u'city', u'func': to_city, 'extra_values': 'country'},
u'Место проведения':{u'field': u'place', u'func': to_place},##### u'Место проведения':{u'field': u'place', u'func': to_place},
u'ID Тематики':{u'field': u'theme', u'func': to_theme, u'method': True}, 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'Теги':{u'field': u'tag', u'func': to_tag, u'method': True},
#u'Организатор №1':{u'field': u'organiser', u'func': to_tag},#### #u'Организатор №1':{u'field': u'organiser', u'func': to_tag},####
#u'Организатор №2':{u'field': u'organiser', u'func': to_tag},#### #u'Организатор №2':{u'field': u'organiser', u'func': to_tag},####
u'Описание события':{u'field': u'description', u'func': unicode}, u'Описание события':{u'field': u'description', u'func': unicode},
u'Периодичность':{u'field': u'periodic', 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'audience', u'func': to_audience},
u'Логотип':{u'field': u'logo', u'func': save_file, u'method': True, u'purpose': 'logo'},
u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url}, u'Официальный веб-сайт':{u'field': u'web_page', u'func': to_url},
u'Экспонируемые продукты':{u'field': u'products', u'func': unicode}, u'Экспонируемые продукты':{u'field': u'products', u'func': unicode},
u'Время работы':{u'field': u'time', 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'Валюта':{u'field': u'currency', u'func': unicode},
# u'Стоимость билета 1 день':{u'field': u'price_day', u'func': unicode},
u'Посетители_билет (1 день)':{u'field': u'price_day', u'func': to_int}, u'Стоимость билета все дни':{u'field': u'price_all', u'func': unicode},
u'Посетители_билет (все дни)':{u'field': u'price_all', u'func': to_int}, u'Условия предварительной регистрации':{u'field': u'pre_condition', u'func': unicode},
u'Условия':{u'field': u'periodic', u'func': unicode}, u'Стоимость на стойке 1 день':{u'field': u'price_day_bar', u'func': unicode},
#u'Посетители_билет (1 день)':{u'field': u'price_day_bar', u'func': to_int},##?? u'Стоимость на стойке все дни':{u'field': u'price_all_bar', u'func': unicode},
#u'Посетители_билет (все дни)':{u'field': u'price_all_bar', u'func': to_int},##?? u'Условия регистрации на стойке':{u'field': u'stand_condition', u'func': unicode},
#u'Условия':{u'field': u'periodic', u'func': unicode},##?? u'Примечание по посещению':{u'field': u'visit_note', u'func': unicode},
#u'Примечание':{u'field': u'periodic', u'func': unicode},
u'Каталог':{u'field': u'price_catalog', u'func': to_int}, u'Каталог':{u'field': u'price_catalog', u'func': to_int},
u'Налог включен':{u'field': u'tax', u'func': bool}, u'Налог включен':{u'field': u'tax', u'func': bool},
u'Год основания':{u'field': u'foundation_year', u'func': to_int}, u'Год основания':{u'field': u'foundation_year', u'func': to_int},
#u'Данные за год':{u'field': u'periodic', 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'visitors', u'func': to_int},
u'Участники':{u'field': u'members', u'func': to_int}, u'Участники':{u'field': u'members', u'func': to_int},
#u'Страны':{u'field': u'periodic', u'func': unicode},##?? u'Страны':{u'field': u'stat_countries', u'func': unicode},
u'Площадь':{u'field': u'periodic', u'func': to_int}, u'Площадь':{u'field': u'area', u'func': to_int},
u'Min_Raw кв.м.':{u'field': u'min_closed_area', 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'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'Min_Pack кв.м.':{u'field': u'min_closed_equipped_area', u'func': to_int},
@ -518,16 +368,13 @@ event_sett = {
u'Открытая площадь':{u'field': u'max_open_area', u'func': to_int}, u'Открытая площадь':{u'field': u'max_open_area', u'func': to_int},
u'Мин. Площадь кв.м.':{u'field': u'min_open_area', u'func': to_int}, u'Мин. Площадь кв.м.':{u'field': u'min_open_area', u'func': to_int},
u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int}, u'Регистрационный взнос':{u'field': u'registration_payment', u'func': to_int},
#u'Примечание':{u'field': u'periodic', u'func': unicode}, u'Примечание по участии':{u'field': u'participation_note', u'func': unicode},
u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date}, u'Крайний срок подачи заявки':{u'field': u'application_deadline', u'func': to_date},
u'UFI':{u'field': u'quality_label', u'func': bool},## 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': bool},## 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': bool},## 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'Отменена':{u'field': u'canceled', u'func': bool},
u'ExpoHIT':{u'field': u'expohit', u'func': bool}, u'ExpoHIT':{u'field': u'expohit', u'func': bool},
u'Фото':{u'field': u'photo', u'func': save_photo, u'method': True},
} }
import_settings={ import_settings={

@ -209,6 +209,9 @@ class ImportPlaceExpositionForm(ImportForm):
class ImportPlaceConferenceForm(ImportForm): class ImportPlaceConferenceForm(ImportForm):
model = PlaceConference model = PlaceConference
from import_xls.excel_settings import event_sett
class ImportEventForm(ImportForm): class ImportEventForm(ImportForm):
""" """
extended form for importing one type of event extended form for importing one type of event
@ -230,13 +233,32 @@ class ImportEventForm(ImportForm):
sheet = book.sheet_by_index(0) sheet = book.sheet_by_index(0)
row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)]
# all field names in excel file (must be in second row) # all field names in excel file (must be in second row)
field_names = [name for name in row_list[1]] field_names = [name for name in row_list[0]]
# model # model
model = get_model(data['event'].split('.')[0], data['event'].split('.')[1]) model = get_model(data['event'].split('.')[0], data['event'].split('.')[1])
list_dicts = []
for row_number, row in enumerate(row_list[1:]):
d = {}
for col_number, cell in enumerate(row):
# through row
field_name = field_names[col_number]
setting = event_sett.get(field_name)
if setting:
d[setting['field']] = {'value':cell}
d['lang'] = lang
list_dicts.append(d)
return list_dicts
for row_number, row in enumerate(row_list): for row_number, row in enumerate(row_list):
# go through all rows in file # go through all rows in file
if row_number > 1: if row_number > 0:
# first two fields are verbose name and name # first two fields are verbose name and name
if row[0] != '': if row[0] != '':
# in first column ids # in first column ids
@ -254,15 +276,27 @@ class ImportEventForm(ImportForm):
object = model() object = model()
object.translate(lang) object.translate(lang)
d = {}
for col_number, cell in enumerate(row): for col_number, cell in enumerate(row):
# through row
field_name = field_names[col_number]
setting = import_settings.get(field_name)
d[setting] = cell
list_dicts.append(d)
"""
# go through row cells # go through row cells
# field name current cell # field name current cell
field_name = field_names[col_number] field_name = field_names[col_number]
if field_name =='theme': if field_name =='theme':
# need save object before saving manytomany field # need save object before saving manytomany field
object.save() #object.save()
setting = import_settings.get(field_name) setting = import_settings.get(field_name)
d[setting] = cell
if setting is not None: if setting is not None:
# if setting exist for this field # if setting exist for this field
func = setting.get('func') func = setting.get('func')
@ -283,8 +317,10 @@ class ImportEventForm(ImportForm):
value = func(cell) value = func(cell)
if value: if value:
setattr(object, field_name, value) setattr(object, field_name, value)
"""
object.save() #object.save()
sadsa

@ -0,0 +1,22 @@
from hvad.models import TranslationManager
class ExpoImportManager(TranslationManager):
def create_by_dict(self, d):
model = self.model
id = d['id']
lang = d['lang']
if id:
expo = self.language(lang).get(id=id)
else:
expo = model()
expo.translate(lang)
aaaa
# save simple values
# save relations

@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
import urllib2
import time, xlrd
from django.conf import settings
from django.utils import translation
from hvad.utils import get_translation_aware_manager
from bitfield import BitHandler
from place_exposition.models import PlaceExposition
from exposition.models import Exposition
from country.models import Country
from city.models import City
from theme.models import Theme, Tag
from functions.files import get_alternative_filename
from exposition.models import BIT_AUDIENCE
def to_int(val):
"""
Reverse function to get_int
return None if value isnt integer
"""
try:
return int(val)
except ValueError:
return None
def to_date(value):
if not value:
return None
if isinstance(value, unicode) or isinstance(value, str):
t = time.strptime(value, "%d.%m.%Y")
if isinstance(value, float):
t = xlrd.xldate_as_tuple(value, 0)+(0,0,0)
return time.strftime("%Y-%m-%d", t)
def to_country(value):
try:
query = get_translation_aware_manager(Country)
country = query.filter(name=value)[0]
return country
except IndexError:
return None
def to_city(value, lang, country):
try:
# get city by name
#objects = get_translation_aware_manager(City)
# except IndexError if no found
city = City.objects.filter(translations__name=value, country=country)[0]
# print(city)
return city
except IndexError:
# print('---------------------')
# print(value.encode('utf8'))
# print('---------------------')
return None
def to_theme(obj, value):
if isinstance(value, float) or isinstance(value, int):
if (value - int(value) > 0):
value = str(value)
else:
value = str(int(value))
theme_ids = value.split('.')
else:
theme_ids = value.split(',')
obj.theme.add(*Theme.objects.filter(id__in=theme_ids))
def to_tag(obj,value):
if value == [""]:
return None
names = value.split(',')
translation.activate('en')
if names:
obj.tag.add(*Tag.objects.filter(translations__name__in=names, theme__in=obj.theme.all()))
else:
return
def to_place(value):
try:
place = PlaceExposition.objects.get(url=value)
return place
except PlaceExposition.DoesNotExist:
return None
def to_periodic(value):
periodic = {'': 0, u'Ежегодно': 1.0, u'2 раза в год': 2.0, u'3 раза в год': 3.0,
u'4 раза в год': 4.0, u'5 раз в год': 5.0, u'Раз в 2 года': 0.5,
u'Раз в 3 года': 0.33, u'Раз в 4 года': 0.25}
return periodic.get(value, 0)
def to_audience(value, model=Exposition):
if value:
l = value.split(', ')
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if value == item2:
new_list.append(item1)
if new_list:
return reduce(lambda x,y: x|y, (getattr(model.audience, item) for item in new_list))
return 0
def get_audience(value):
if isinstance(value, BitHandler):
l = [k for k, v in value.iteritems() if v]
if l:
new_list = []
for value in l:
for item1, item2 in BIT_AUDIENCE:
if value == item1:
new_list.append(item2)
return ', '.join(new_list)
return
def save_logo(obj, path):
if not path:
return None
file_name = path.split('/')[-1]
logo_path = obj.logo.field.upload_to
full_path = settings.MEDIA_ROOT + logo_path
alt_name = get_alternative_filename(full_path, file_name)
download_to = full_path+alt_name
if path.startswith('http://') or path.startswith('https://'):
url = path
else:
url = 'http://expomap.ru' + path
try:
response = urllib2.urlopen(url, timeout=10)
except:
return None
with open(download_to,'wb') as f:
try:
f.write(response.read())
f.close()
except:
# can be timeout
return None
obj.logo = logo_path + alt_name
obj.save()
def check_quality_label(obj, value, label):
bit = obj.quality_label
try:
value = int(value)
except:
return bit
if value:
setattr(bit, label, True)
return bit

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save