From 6ae0c99bce37ebb82a4a6a78f4e8196c486c1f28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B0=D0=B7=D0=B0=D1=80=20=D0=9A=D0=BE=D1=82=D1=8E?= =?UTF-8?q?=D0=BA?= Date: Thu, 19 Feb 2015 18:44:47 +0200 Subject: [PATCH 1/2] Import task(38) --- accounts/models.py | 50 ------------- .../management/commands/articles_from_old.py | 41 +++++++++- article/management/commands/news_from_old.py | 59 +++++++++++++++ article/models.py | 56 +------------- article/urls.py | 2 + article/views.py | 2 + company/models.py | 6 ++ core/simple_index_view.py | 7 +- exposition/admin.py | 22 +++--- exposition/forms.py | 55 ++++++++++++-- exposition/management/commands/expo_test.py | 74 +++++++++++++++++++ exposition/management/commands/fix_logo.py | 31 ++++++-- exposition/management/commands/imp_stat.py | 65 ++++++++++++++++ exposition/models.py | 21 ++++-- proj/admin.py | 32 ++++++++ proj/admin_urls.py | 2 + service/models.py | 14 +++- service/order_forms.py | 6 +- service/urls.py | 11 ++- service/views.py | 26 +++++++ settings/templatetags/template_filters.py | 32 +++++++- static/custom_js/main.js | 47 ++++++++++++ templates/admin/base.html | 17 ++++- templates/admin/exposition/exposition.html | 37 +++++++++- templates/admin/includes/stat_form.html | 58 +++++++++++++++ templates/admin/service/order_list.html | 37 ++++++++++ templates/client/article/blog_list.html | 8 +- templates/client/article/news_list.html | 6 +- templates/client/exposition/statistic.html | 34 ++++++++- .../includes/accounts/current_user.html | 2 +- .../client/includes/accounts/simple_user.html | 2 +- .../client/includes/company/company_edit.html | 4 +- .../includes/company/company_object.html | 4 +- .../client/includes/exposition/statistic.html | 36 +++------ templates/client/popups/callback.html | 4 +- theme/views.py | 3 +- 36 files changed, 729 insertions(+), 184 deletions(-) create mode 100644 article/management/commands/news_from_old.py create mode 100644 exposition/management/commands/expo_test.py create mode 100644 exposition/management/commands/imp_stat.py create mode 100644 templates/admin/includes/stat_form.html create mode 100644 templates/admin/service/order_list.html diff --git a/accounts/models.py b/accounts/models.py index 1ca10054..909e2bda 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -409,53 +409,3 @@ def post_profile(sender, instance, created, **kwargs): post_save.connect(create_user_inf, sender=User) post_save.connect(post_profile, sender=Profile) -#need import after User Model, because User imported in "organiser.models" -#from organiser.models import Organiser - -''' -def create_profiles(sender, **kw): - """ - create Translator profile if "is_translator" field in User model true - if it's false delete Translator profile connected to User - - create Organiser profile if "is_organiser" field in User model true - if it's false delete Organiser profile connected to User - """ - user = kw["instance"] - - if user.is_translator and not user.translator.all(): - #check flag is_translator and if translator profile already exist - translator = TranslatorProfile(user=user) - translator.save() - - if not user.is_translator: - TranslatorProfile.objects.filter(user = user).delete() - - - if user.is_organiser and not user.organiser.all(): - #check flag is_organiser and if organiser profile already exist - organiser = Organiser(user=user) - - if user.country: - organiser.country = user.country - - if user.city: - organiser.city = user.city - - organiser.save() - - - data = {'name_ru':user.get_full_name()} - - zero_fields = {} - fill_trans_fields_all(Organiser, organiser, data, None, zero_fields) - #populate empty fields and fields which was already populated - organiser_id = getattr(organiser, 'id') - populate_all(Organiser, data, organiser_id, zero_fields) - - if not user.is_organiser: - Organiser.objects.filter(user = user).delete() - - -post_save.connect(create_profiles, sender=User) -''' diff --git a/article/management/commands/articles_from_old.py b/article/management/commands/articles_from_old.py index 51bbda1f..358a13fe 100644 --- a/article/management/commands/articles_from_old.py +++ b/article/management/commands/articles_from_old.py @@ -4,6 +4,7 @@ from MySQLdb.cursors import DictCursor from django.core.management.base import BaseCommand, CommandError from functions.translate import fill_with_signal from article.models import Article +from accounts.models import User class Command(BaseCommand): @@ -15,8 +16,46 @@ class Command(BaseCommand): charset='utf8', cursorclass=DictCursor) cursor = db.cursor() - sql = """SELECT articles_description.articles_id as id , articles_description.articles_name as name, articles_description.articles_description as description, articles_description.articles_head_title_tag as title, articles_description.articles_head_desc_tag as descriptions, articles_description.articles_head_keywords_tag as keywords, articles_description.articles_intro as main_title, articles.articles_date_added as created, articles.articles_last_modified as modified + sql = """SELECT articles_description.articles_id as id , + articles_description.articles_name as main_title, + articles_description.articles_description as description, + articles.authors_id as author, + articles_description.articles_intro as preview, + articles.articles_date_added as created, + articles.articles_last_modified as modified, + articles.articles_date_available as publish_date, + articles_description.articles_head_title_tag as title, + articles_description.articles_head_desc_tag as descriptions, + articles_description.articles_head_keywords_tag as keywords + FROM `articles_description` JOIN articles ON articles_description.articles_id=articles.articles_id""" + cursor.execute(sql) + + result = cursor.fetchall() + user = User.objects.get(id=1) + for a in result: + article = Article(type=Article.blog, + id=a['id'], + created=a['created'], + modified=a['modified'], + publish_date=a['publish_date']) + + article.author = user + + article.translate('ru') + article.main_title = a['main_title'] + article.preview = a['preview'] + article.description = a['description'] + article.title = a['title'] + article.keywords = a['keywords'] + if len(a['descriptions'])<255: + article.descriptions = a['descriptions'] + article.save() + print(article) + + #print(a['main_title']) + + diff --git a/article/management/commands/news_from_old.py b/article/management/commands/news_from_old.py new file mode 100644 index 00000000..6a975707 --- /dev/null +++ b/article/management/commands/news_from_old.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +import MySQLdb +from MySQLdb.cursors import DictCursor +from django.core.management.base import BaseCommand, CommandError +from functions.translate import fill_with_signal +from article.models import Article +from accounts.models import User + + +class Command(BaseCommand): + def handle(self, *args, **options): + db = MySQLdb.connect(host="localhost", + user="kotzilla", + passwd="qazedc", + db="old_expomap", + charset='utf8', + cursorclass=DictCursor) + cursor = db.cursor() + sql = """SELECT news_id as id , + headline as main_title, + content as description, + cid as author, + date_added as created + + FROM `latest_news`""" + + cursor.execute(sql) + + result = cursor.fetchall() + user = User.objects.get(id=1) + + c = 0 + for a in result: + if len(a['main_title'])>255 or not a['main_title']: + continue + article = Article(type=Article.news, + id=a['id'], + created=a['created']) + if a['author']: + try: + author = User.objects.get(id=a['author']) + except User.DoesNotExist: + author = user + else: + author = user + + article.author = author + + article.translate('ru') + article.main_title = a['main_title'] + article.description = a['description'] + article.save() + print(article) + + + #print(a['main_title']) + + + diff --git a/article/models.py b/article/models.py index 6f65aaa3..759639bd 100644 --- a/article/models.py +++ b/article/models.py @@ -81,7 +81,7 @@ class Article(TranslatableModel): #translated fields translations = TranslatedFields( - main_title = models.CharField(max_length=100), + main_title = models.CharField(max_length=255), preview = models.TextField(), description = models.TextField(), #-----meta @@ -184,60 +184,6 @@ class Article(TranslatableModel): """ return self._get_next_or_previous_by_publish_date(False, **kwargs) - def clone(self): - """ - Return an identical copy of the instance with a new ID. - """ - if not self.pk: - raise ValueError('Instance must be saved before it can be cloned.') - - duplicate = copy.copy(self) - # Setting pk to None. Django thinking this is a new object. - duplicate.pk = None - # url must be unique - duplicate.url += '_copy' - if Article.objects.safe_get(url=duplicate.url): - #already has copy this instance - return - - ignore_fields = ['id', 'master', 'language_code'] - duplicate.translate('ru') - tr = self._meta.translations_model.objects.get(language_code = 'ru',master__id=self.pk) - for field in duplicate._translated_field_names: - - if field in ignore_fields: - continue - - setattr(duplicate, field, getattr(tr, field)) - - duplicate.save() - # but lost all ManyToMany relations and Translations. - ''' - # copy relations - for field in self._meta.many_to_many: - source = getattr(self, field.attname) - destination = getattr(duplicate, field.attname) - for item in source.all(): - destination.add(item) - - # copy translations - languages = self.get_available_languages() - ignore_fields = ['id', 'master', 'language_code'] - - for code in languages: - duplicate.translate(code) - tr = self._meta.translations_model.objects.get(language_code = code,master__id=self.pk) - for field in duplicate._translated_field_names: - - if field in ignore_fields: - continue - - setattr(duplicate, field, getattr(tr, field)) - - duplicate.save() - ''' - - return duplicate def admin_url(self): if self.type == 1: diff --git a/article/urls.py b/article/urls.py index 84a18675..bdd15307 100644 --- a/article/urls.py +++ b/article/urls.py @@ -3,7 +3,9 @@ from django.conf.urls import patterns, url from views import BlogList, NewsList, BlogDetail, NewsDetail urlpatterns = patterns('', + url(r'blogs/page/(?P\d+)/$', BlogList.as_view()), url(r'blogs/$', BlogList.as_view()), + url(r'news/page/(?P\d+)/$', NewsList.as_view()), url(r'news/$', NewsList.as_view()), url(r'blogs/(?P.*)$', BlogDetail.as_view()), url(r'news/(?P.*)$', NewsDetail.as_view()), diff --git a/article/views.py b/article/views.py index 862e73fb..3bce10e5 100644 --- a/article/views.py +++ b/article/views.py @@ -5,6 +5,7 @@ from models import Article class NewsList(ListView): model = Article template_name = 'article/news_list.html' + paginate_by = 10 def get_queryset(self): if self.request.GET: @@ -30,6 +31,7 @@ class NewsDetail(DetailView): class BlogList(ListView): model = Article template_name = 'article/blog_list.html' + paginate_by = 10 def get_queryset(self): if self.request.GET: diff --git a/company/models.py b/company/models.py index a0f51621..d47a8fd5 100644 --- a/company/models.py +++ b/company/models.py @@ -128,7 +128,13 @@ def calculate_rating(company): if getattr(company, key): rating += value + themes = company.theme.all().count() + rating += themes * 10 + tags = company.tag.all().count() + rating += tags * 10 if tags < 6 else 50 + company.rating = rating + # call to prevent recursion post_save.disconnect(create_company, sender=Company) company.save() diff --git a/core/simple_index_view.py b/core/simple_index_view.py index 1213a94c..182bb9a8 100644 --- a/core/simple_index_view.py +++ b/core/simple_index_view.py @@ -1,7 +1,8 @@ import json from django.views.generic import TemplateView from django.shortcuts import HttpResponse -from forms import CallbackForm +#from forms import CallbackForm +from service.order_forms import CallBackForm class AdvertisingView(TemplateView): @@ -15,9 +16,9 @@ class AboutView(TemplateView): def callback(request): response = {'success': False} if request.GET: - form = CallbackForm(request.GET) + form = CallBackForm(request.GET) if form.is_valid(): - form.send() + form.save() response['success'] = True else: response['errors'] = form.errors diff --git a/exposition/admin.py b/exposition/admin.py index e5309b23..4d73f439 100644 --- a/exposition/admin.py +++ b/exposition/admin.py @@ -241,11 +241,11 @@ class ExpositionView(AdminView): template_name = 'admin/exposition/exposition.html' def form_valid(self, form): - StatisticFormSet = formset_factory(StatisticForm) - formset_statistic = StatisticFormSet(self.request.POST) + #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() @@ -255,7 +255,7 @@ class ExpositionView(AdminView): statistic = item.save(commit=False) statistic.exposition = expo statistic.save() - + """ return HttpResponseRedirect(self.success_url) @@ -331,20 +331,22 @@ class ExpositionView(AdminView): context = super(ExpositionView, self).get_context_data(**kwargs) obj = self.set_obj() if obj: - StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',)) + #StatisticFormSet = modelformset_factory(Statistic, form=StatisticForm, exclude=('exposition',)) # get existing statistic - statistic = Statistic.objects.filter(exposition=getattr(obj, 'id')) + #statistic = Statistic.objects.filter(exposition=getattr(obj, 'id')) # fill HallFormSet - formset_statistic = StatisticFormSet(queryset=statistic) + #formset_statistic = StatisticFormSet(queryset=statistic) + context['stat_form'] = StatisticForm() 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() + #StatisticFormSet = formset_factory(StatisticForm) + #formset_statistic = StatisticFormSet() + pass - context['formset_statistic'] = formset_statistic + #context['formset_statistic'] = formset_statistic context['photo_form'] = PhotoForm() context['timetable_form'] = TimeTableForm() diff --git a/exposition/forms.py b/exposition/forms.py index cede88a6..289e2523 100644 --- a/exposition/forms.py +++ b/exposition/forms.py @@ -462,14 +462,48 @@ class ExpositionDeleteForm(forms.ModelForm): fields = ('url',) -class StatisticForm(forms.ModelForm): - year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'})) - visitors = 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: - model = Statistic - exclude = ('exposition') +class StatisticForm(forms.Form): + year = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), label='Год') + visitors = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Посетители') + members = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Участники') + area = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Площадь') + countries_number = forms.CharField(widget=forms.TextInput(attrs={'style': 'width:70px'}), required=False, label='Число стран') + + def __init__(self, *args, **kwargs): + """ + create dynamical translated fields fields + """ + super(StatisticForm, self).__init__(*args, **kwargs) + #creates translated forms 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): + # uses enumerate for detect iteration number + # first iteration is a default lang so it required fields + required = True if lid == 0 else False + self.fields['countries_%s' % code] = forms.CharField(label=u'Участвующие страны', + required=False, + widget=forms.TextInput(attrs={'style':'width: 250px'})) + + def save(self, exposition=None): + data = self.cleaned_data + if not exposition: + return None + else: + stat = Statistic() + + # simple fields + + stat.exposition = exposition + stat.year = data['year'] + stat.visitors = data.get('visitors') + stat.members = data.get('members') + stat.area = data.get('area') + stat.countries_number = data.get('countries_number') + + fill_with_signal(Statistic, stat, data) + + return stat def clean_year(self): cleaned_data = super(StatisticForm, self).clean() @@ -486,6 +520,11 @@ class StatisticForm(forms.ModelForm): visitors = cleaned_data.get('visitors').strip() return is_positive_integer(visitors) + def clean_countries_number(self): + cleaned_data = super(StatisticForm, self).clean() + countries_number = cleaned_data.get('countries_number').strip() + return is_positive_integer(countries_number) + from functions.files import check_tmp_timetables class TimeTableForm(forms.Form): diff --git a/exposition/management/commands/expo_test.py b/exposition/management/commands/expo_test.py new file mode 100644 index 00000000..8f4197d0 --- /dev/null +++ b/exposition/management/commands/expo_test.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +import xlrd +import urllib2 +from django.core.management.base import BaseCommand +from django.conf import settings +from functions.form_check import translit_with_separator +from functions.files import get_alternative_filename +from exposition.models import Exposition, Statistic +from organiser.models import Organiser + + +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' + +LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx' +NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls' +NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls' + +# 44 +class Command(BaseCommand): + def handle(self, *args, **options): + qs = Statistic.objects.language('ru').exclude(translations__countries='') + comas = 0 + enters = 0 + main = 0 + spaces = 0 + word = 0 + number = 0 + for i in qs: + if ';' in i.countries: + main +=1 + a = i.countries.split(';') + new = [item.strip() for item in a] + + st = ';'.join(new) + print st.encode('utf8') + i.countries = st + #i.save() + elif ',' in i.countries: + comas += 1 + + + elif '\n' in i.countries: + enters += 1 + elif ' ' in i.countries: + spaces += 1 + if '55' in i.countries: + continue + + + elif '.' in i.countries: + number += 1 + #a = i.countries.split('.') + #i.countries_number = int(a[0]) + #i.countries = '' + #i.save() + + else: + word += 1 + + + + print('all: %d'%qs.count()) + print('main: %d'%main) + print('comas: %d'%comas) + print('enter: %d'%enters) + print('spaces: %d'%spaces) + print('word: %d'%word) + print('number: %d'%number) + diff --git a/exposition/management/commands/fix_logo.py b/exposition/management/commands/fix_logo.py index 554fd78c..4d3f89ce 100644 --- a/exposition/management/commands/fix_logo.py +++ b/exposition/management/commands/fix_logo.py @@ -24,7 +24,7 @@ NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls' class Command(BaseCommand): def handle(self, *args, **options): - f = open(NA_EU_ASIA_FILE2, 'r') + f = open(CHINA_FILE, 'r') book = xlrd.open_workbook(file_contents=f.read()) sheet = book.sheet_by_index(0) row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] @@ -37,25 +37,40 @@ class Command(BaseCommand): except Exposition.DoesNotExist: continue - if row[16] =='' or row[16].startswith('http') or row[16].startswith('https') or row[16].startswith('/') or row[16].startswith('../'): + if exp.logo or row[19] == '':# or row[16].startswith('http') or row[16].startswith('https') or not row[16].startswith('/') or row[16].startswith('../'): continue - path = row[16] - - + path = row[19] file_name = path.split('/')[-1] logo_path = exp.logo.field.upload_to full_path = settings.MEDIA_ROOT + logo_path - - alt_name = get_alternative_filename(full_path, file_name) + try: + alt_name = get_alternative_filename(full_path, file_name) + except UnicodeEncodeError: + continue download_to = full_path+alt_name - url = 'http://expomap.ru/' + path + + if path.startswith('http') or path.startswith('https'): + url = path + elif path.startswith('/'): + url = 'http://expomap.ru' + path + elif path.startswith('images'): + url = 'http://expomap.ru/' + path + else: + continue + #print('------------------------------------') + #print(path) + #print(url) + #print('------------------------------------') + try: response = urllib2.urlopen(url, timeout=15) except: continue + if response.code != 200: + continue with open(download_to,'wb') as f: try: diff --git a/exposition/management/commands/imp_stat.py b/exposition/management/commands/imp_stat.py new file mode 100644 index 00000000..c62854a3 --- /dev/null +++ b/exposition/management/commands/imp_stat.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +import xlrd +import urllib2 +from django.core.management.base import BaseCommand +from django.conf import settings +from functions.form_check import translit_with_separator +from functions.files import get_alternative_filename +from exposition.models import Exposition, Statistic +from organiser.models import Organiser + + +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' + +LA_FILE = settings.MEDIA_ROOT+'/import/expo_la.xlsx' +NA_EU_ASIA_FILE = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa.xls' +NA_EU_ASIA_FILE2 = settings.MEDIA_ROOT+'/import/expo_na_eu_ sa_part2.xls' + + +class Command(BaseCommand): + def handle(self, *args, **options): + + f = open(NA_EU_ASIA_FILE, 'r') + book = xlrd.open_workbook(file_contents=f.read()) + sheet = book.sheet_by_index(0) + row_list = [sheet.row_values(row_number) for row_number in range(sheet.nrows)] + labels = [label for label in row_list[0]] + + for row_number, row in enumerate(row_list[1:]): + exp_url = translit_with_separator(row[2]) + try: + exp = Exposition.objects.language('ru').get(url=exp_url) + except Exposition.DoesNotExist: + continue + if not row[30]: + continue + + year = int(row[30]) + try: + countries_number = int(exp.stat_countries) + countries = '' + except ValueError: + countries_number = None + countries = exp.stat_countries + + members = exp.members + visitors = exp.visitors + area = exp.area + + + s = Statistic(exposition=exp, + year=year, + countries_number=countries_number, + members=members, + visitors=visitors, + area=area) + s.translate('ru') + s.countries = countries + s.save() + + print(exp) \ No newline at end of file diff --git a/exposition/models.py b/exposition/models.py index e815ae55..5c7ef174 100644 --- a/exposition/models.py +++ b/exposition/models.py @@ -327,12 +327,22 @@ class Exposition(TranslatableModel, EventMixin, ExpoMixin): return duplicate -class Statistic(models.Model): +class Statistic(TranslatableModel): exposition = models.ForeignKey(Exposition, related_name='statistic') year = models.PositiveIntegerField(verbose_name='Год') - members = models.PositiveIntegerField(verbose_name='Посетители') - visitors = models.PositiveIntegerField(verbose_name='Участники') - area = models.PositiveIntegerField(verbose_name='Площадь') + members = models.PositiveIntegerField(verbose_name='Посетители', blank=True, null=True) + visitors = models.PositiveIntegerField(verbose_name='Участники', blank=True, null=True) + area = models.PositiveIntegerField(verbose_name='Площадь', blank=True, null=True) + countries_number = models.PositiveIntegerField(verbose_name='Количество стран', blank=True, null=True) + + translations = TranslatedFields( + countries = models.TextField(blank=True) + ) + + def to_dict(self): + return hvad_to_dict(self) + + from django.core import serializers from functions.models_methods import hvad_to_dict @@ -409,4 +419,5 @@ class TmpTimeTable(TranslatableModel): pre_save.connect(pre_save_handler, sender=Exposition) post_save.connect(post_save_handler, sender=Exposition) post_save.connect(post_save_handler, sender=TimeTable) -post_save.connect(post_save_handler, sender=TmpTimeTable) \ No newline at end of file +post_save.connect(post_save_handler, sender=TmpTimeTable) +post_save.connect(post_save_handler, sender=Statistic) \ No newline at end of file diff --git a/proj/admin.py b/proj/admin.py index 1d2114b2..1d9ebb3c 100644 --- a/proj/admin.py +++ b/proj/admin.py @@ -159,6 +159,38 @@ def ajax_post_timetable(request, obj_id=None): else: return HttpResponse('error') +from exposition.models import Statistic +from exposition.forms import StatisticForm +def ajax_post_stat(request, obj_id=None): + response = {'success': False} + if request.GET: + form = StatisticForm(request.GET) + if form.is_valid(): + + exp = Exposition.objects.safe_get(id=obj_id) + if exp: + form.save(exp) + response['success'] = True + else: + response.update({'errors': form.errors}) + + return HttpResponse(json.dumps(response), content_type='application/json') + +def ajax_delete_stat(request, id): + redirect_to = request.META.get('HTTP_REFERER') + + + if id: + try: + Statistic.objects.get(id=id).delete() + except Statistic.DoesNotExist: + pass + + + return HttpResponseRedirect(redirect_to) + + + def ajax_delete_timetable(request): if request.GET: diff --git a/proj/admin_urls.py b/proj/admin_urls.py index f499cc8c..55e492a1 100644 --- a/proj/admin_urls.py +++ b/proj/admin_urls.py @@ -36,6 +36,8 @@ urlpatterns = required( url(r'^ajax_post_file/', 'proj.admin.ajax_post_file'), url(r'^ajax_post_photo/(?P\d+)/$', 'proj.admin.ajax_post_photo'),#must be before /ajax_post_photo/ url(r'^ajax_post_photo/', 'proj.admin.ajax_post_photo'), + url(r'^ajax_post_stat/(?P\d+)/$', 'proj.admin.ajax_post_stat'), + url(r'^ajax_delete_stat/(?P\d+)/', 'proj.admin.ajax_delete_stat'), url(r'^ajax_post_timetable/(?P\d+)/$', 'proj.admin.ajax_post_timetable'),#must be before /ajax_post_timetable/ url(r'^ajax_post_timetable/', 'proj.admin.ajax_post_timetable'), url(r'^ajax_delete_timetable/', 'proj.admin.ajax_delete_timetable'), diff --git a/service/models.py b/service/models.py index 28ca45b4..9ac38dcd 100644 --- a/service/models.py +++ b/service/models.py @@ -65,9 +65,12 @@ class AbstractOrder(models.Model): exposition = models.ForeignKey('exposition.Exposition', null=True) conference = models.ForeignKey('conference.Conference', null=True) seminar = models.ForeignKey('seminar.Seminar', null=True) + created = models.DateTimeField(auto_now_add=True) + viewed = models.DateTimeField(null=True, blank=True) class Meta: abstract = True + ordering = ['-created'] @@ -124,4 +127,13 @@ class Visit(AbstractOrder): notes = models.TextField(blank=True) class Advertising(AbstractOrder): - pass \ No newline at end of file + pass + +class CallBack(models.Model): + phone = models.CharField(max_length=30) + person_inf = models.CharField(max_length=255) + created = models.DateTimeField(auto_now_add=True) + viewed = models.DateTimeField(null=True, blank=True) + + class Meta: + ordering = ['-created'] \ No newline at end of file diff --git a/service/order_forms.py b/service/order_forms.py index 12d6dbfc..d5f69b79 100644 --- a/service/order_forms.py +++ b/service/order_forms.py @@ -2,7 +2,7 @@ from django import forms from django.utils.translation import ugettext as _ from accounts.models import User -from models import Catalog, Tickets, Remote, Participation, Translation, Visit, CURENCIES, Advertising +from models import Catalog, Tickets, Remote, Participation, Translation, Visit, CURENCIES, Advertising, CallBack from exposition.models import Exposition from conference.models import Conference from seminar.models import Seminar @@ -202,3 +202,7 @@ class AdvertiseForm(AbstractOrderForm): class Meta: model = Advertising +class CallBackForm(forms.ModelForm): + class Meta: + model = CallBack + fields=('phone', 'person_inf') \ No newline at end of file diff --git a/service/urls.py b/service/urls.py index 44ef4f0f..66da4a43 100644 --- a/service/urls.py +++ b/service/urls.py @@ -1,10 +1,19 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url -from views import ServiceView +from views import ServiceView, CallBackListView, VisitListView, TranslationListView, AdvertisingListView, \ + ParticipationListView, RemoteListView,TicketsListView urlpatterns = patterns('', + url(r'service/order/callback/$', CallBackListView.as_view()), + url(r'service/order/visit/$', VisitListView.as_view()), + url(r'service/order/translation/$', TranslationListView.as_view()), + url(r'service/order/advertising/$', AdvertisingListView.as_view()), + url(r'service/order/participation/$', ParticipationListView.as_view()), + url(r'service/order/remote/$', RemoteListView.as_view()), + url(r'service/order/tickets/$', TicketsListView.as_view()), url(r'service/advertise/$', 'service.views.advertise'), url(r'service/(?P.*)/$', ServiceView.as_view()), + ) diff --git a/service/views.py b/service/views.py index b6ea0fd8..718918bc 100644 --- a/service/views.py +++ b/service/views.py @@ -48,5 +48,31 @@ def advertise(request): return HttpResponse(json.dumps(response), content_type='application/json') +from service.models import CallBack, Visit, Translation, Advertising, Participation, Remote, Tickets +class AbstractOrderListView(ListView): + template_name = 'admin/service/order_list.html' + paginate_by = 20 +class CallBackListView(AbstractOrderListView): + model = CallBack + + +class VisitListView(AbstractOrderListView): + model = Visit + + +class TranslationListView(AbstractOrderListView): + model = Translation + +class AdvertisingListView(AbstractOrderListView): + model = Advertising + +class ParticipationListView(AbstractOrderListView): + model = Participation + +class RemoteListView(AbstractOrderListView): + model = Remote + +class TicketsListView(AbstractOrderListView): + model = Tickets diff --git a/settings/templatetags/template_filters.py b/settings/templatetags/template_filters.py index 4710925d..37d44578 100644 --- a/settings/templatetags/template_filters.py +++ b/settings/templatetags/template_filters.py @@ -246,4 +246,34 @@ def in_events(day, events): @register.filter def base64_encode(value): - return base64.b64encode(value) \ No newline at end of file + return base64.b64encode(value) + + +@register.filter +def generate_countries_list(value): + values = value.split(';') + values.sort() + if len(values) >= 2: + ul1 = values[::3] + ul2 = values[1::3] + ul3 = values[2::3] + elif len(values) >= 2: + ul1 = values[::2] + ul2 = values[1::2] + ul3 = [] + else: + ul1 = values + ul2 = [] + ul3 = [] + + ul1_html = ''.join(['
  • %s
  • '%i for i in ul1]) + ul2_html = ''.join(['
  • %s
  • '%i for i in ul2]) + ul3_html = ''.join(['
  • %s
  • '%i for i in ul3]) + + ul1 ='
      ' + ul1_html + '
    ' + ul2 ='
      ' + ul2_html + '
    ' + ul3 ='
      ' + ul3_html + '
    ' + + + + return ul1+ul2+ul3 \ No newline at end of file diff --git a/static/custom_js/main.js b/static/custom_js/main.js index b9989d43..4826e93e 100644 --- a/static/custom_js/main.js +++ b/static/custom_js/main.js @@ -86,6 +86,30 @@ function postTimetable(data, textStatus){ } } +function postStat(data, textStatus){ + if(data.success){ + location.reload; + } + else{ + $.each(data.errors, function(field_name, errors){ + $('#id_'+field_name).parent().parent().addClass('error'); + }) + } + /* + if (data instanceof Object){ + $.each(data, function(field_name, errors){ + $('#id_'+field_name).parent().parent().addClass('error'); + }) + } + else{ + $('#stat_modal table tbody').html(data); + $('#stat_form')[0].reset(); + $('#stat_form .control-group').removeClass('error'); + $('#close_stat').click(); + } + */ + } + $(document).ready(function(){ @@ -350,6 +374,29 @@ $(document).ready(function(){ });//end get });//end change + $('#stat_form').on('submit', function(e){//submit(function(){ + e.preventDefault(); + var url = '/admin/ajax_post_stat/' + $('#obj_id').val() + '/'; + console.log(url) + var formData = $(this).serialize(); + + $.ajax({ + url: url, //server script to process data + type: 'GET', + + //Ajax events + success: postStat, + error: function(){ alert('error'); }, + // Form data + data: formData, + //Options to tell JQuery not to process data or worry about content-type + cache: false, + contentType: false, + processData: false + });//end ajax + + }); // end submit + $('#timetable_form').on('submit', function(e){//submit(function(){ e.preventDefault(); tinyMCE.triggerSave(); diff --git a/templates/admin/base.html b/templates/admin/base.html index 87b392d3..850ca929 100644 --- a/templates/admin/base.html +++ b/templates/admin/base.html @@ -112,8 +112,8 @@ + + diff --git a/templates/admin/exposition/exposition.html b/templates/admin/exposition/exposition.html index 1babf44a..54d57c7b 100644 --- a/templates/admin/exposition/exposition.html +++ b/templates/admin/exposition/exposition.html @@ -494,6 +494,39 @@ + {% if object %} +
    + + + + + + + + + + + + + {% for stat in object.statistic.all %} + + + + + + + + {% endfor %} + +
    ГодПосетителиУчастникиПлощадь
    {{ stat.year }}{{ stat.visitors }}{{ stat.members }}{{ stat.area }} Удалить
    +
    + Добавить год + + + + {% else %} + {% endif %} + {% comment %} {% if formset_statistic.errors %}
    {% for form in formset_statistic.forms %} @@ -536,6 +569,7 @@

    Добавить год

    + {% endcomment %}
    @@ -647,7 +681,7 @@ {% include 'admin/includes/photo_form.html' with form=photo_form object=object %} {% include 'admin/includes/file_form.html' with file_form=file_form object=object %} +{% include 'admin/includes/stat_form.html' with form=stat_form object=object %} {% endblock %} diff --git a/templates/admin/includes/stat_form.html b/templates/admin/includes/stat_form.html new file mode 100644 index 00000000..2dc8f5c9 --- /dev/null +++ b/templates/admin/includes/stat_form.html @@ -0,0 +1,58 @@ + \ No newline at end of file diff --git a/templates/admin/service/order_list.html b/templates/admin/service/order_list.html new file mode 100644 index 00000000..e583a22a --- /dev/null +++ b/templates/admin/service/order_list.html @@ -0,0 +1,37 @@ +{% extends 'base.html' %} + +{% block body %} + +
    +
    +

    Список заказов

    +
    +
    + + + + + + + + + + + {% for item in object_list %} + + + + + + + {% endfor %} + +
    idКонтактное лицоТелефонВремя создания
    {{ item.id }}{{ item.person_inf }}{{ item.phone }}{{ item.created }}
    +
    + + {% include 'admin/includes/admin_pagination.html' with page_obj=page_obj %} +
    + {# pagination #} + + +{% endblock %} \ No newline at end of file diff --git a/templates/client/article/blog_list.html b/templates/client/article/blog_list.html index 57300a40..892bd30e 100644 --- a/templates/client/article/blog_list.html +++ b/templates/client/article/blog_list.html @@ -12,7 +12,7 @@ {% block page_title %}
    -

    {% trans 'Статьи' %}:

    +

    {% trans 'Статьи' %}

    {% endblock %} @@ -105,11 +105,15 @@

    {{ blog.main_title }}

    {{ blog.preview }} - {{ blog.publish_date }}{% include 'includes/article_tags.html' with obj=blog %} + {{ blog.created|date:"d E Y" }}{% if blog.tag.all.exists %}{% include 'includes/article_tags.html' with obj=blog %}{% endif %}
    {% endfor %} +{% endblock %} + +{% block paginator %} + {% include 'includes/catalog_paginator.html' with page_obj=page_obj %} {% endblock %} \ No newline at end of file diff --git a/templates/client/article/news_list.html b/templates/client/article/news_list.html index eb38670b..9c3a577d 100644 --- a/templates/client/article/news_list.html +++ b/templates/client/article/news_list.html @@ -103,10 +103,14 @@ {% include 'includes/article/news_preview.html' with obj=news %}

    {{ news.main_title }}

    {{ news.preview }} - {{ news.publish_date }}{{ news.get_event }} + {{ news.created|date:"d E Y" }}{% with event=news.get_event %}{% if event %}{{ event.name }}{% endif %}{% endwith %} {% endfor %} {% endblock %} + +{% block paginator %} + {% include 'includes/catalog_paginator.html' with page_obj=page_obj %} +{% endblock %} diff --git a/templates/client/exposition/statistic.html b/templates/client/exposition/statistic.html index 6d850642..ba03edd0 100644 --- a/templates/client/exposition/statistic.html +++ b/templates/client/exposition/statistic.html @@ -1,4 +1,5 @@ {% extends 'base_catalog.html' %} +{% load static %} {% load template_filters %} {% load i18n %} @@ -19,8 +20,39 @@ {% block content_list %} {% include 'client/includes/exposition/statistic.html' with exposition=object %} + + {% endblock %} {% block paginator %} -{% endblock %} \ No newline at end of file +{% endblock %} + diff --git a/templates/client/includes/accounts/current_user.html b/templates/client/includes/accounts/current_user.html index 47abd31f..886b7d5f 100644 --- a/templates/client/includes/accounts/current_user.html +++ b/templates/client/includes/accounts/current_user.html @@ -438,7 +438,7 @@
    -

    {{ about_form.about.value }}

    +

    {{ about_form.about.value|linebreaks }}

    {% trans 'редактировать' %} diff --git a/templates/client/includes/accounts/simple_user.html b/templates/client/includes/accounts/simple_user.html index 2d71d955..63e94c92 100644 --- a/templates/client/includes/accounts/simple_user.html +++ b/templates/client/includes/accounts/simple_user.html @@ -35,7 +35,7 @@
    - {{ member.profile.about_company|safe }} + {{ member.profile.about_company|safe|linebreaks }}

    diff --git a/templates/client/includes/company/company_edit.html b/templates/client/includes/company/company_edit.html index c9dbb0fe..ff91dcff 100644 --- a/templates/client/includes/company/company_edit.html +++ b/templates/client/includes/company/company_edit.html @@ -157,7 +157,7 @@