diff --git a/accounts/admin.py b/accounts/admin.py index 81eac80e..9457de21 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -13,12 +13,9 @@ from django.utils.translation import ugettext as _ from models import User from forms import UserForm, UserCreationForm, ChangePasswordForm, EmailAnnouncementForm, UserFilterForm #custom views +from django.views.generic import UpdateView from functions.admin_views import AdminView, AdminListView, paginate_results - - - - class UserListView(AdminListView): template_name = 'admin/accounts/user_list.html' form_class = UserFilterForm @@ -31,25 +28,35 @@ class UserListView(AdminListView): context['object_list'] = result return context +class EditUser(UpdateView): + model = User + form_class = UserForm + success_url = '/admin/accounts/all' + template_name = 'user_change.html' + + def user_change(request, url): """ Return form of user and post it on the server. If form is posted redirect on the page of all users. """ - user = User.objects.safe_get(id=url) - # try get user by url if doesnt work by id - if user is None: - user = User.objects.safe_get(url=url) - # redirect to list of all users if cannot find user - if user is None: + try: + user = User.objects.get(url=url) + except User.DoesNotExist: + try: + user = User.objects.get(id=url) + except User.DoesNotExist, User.MultipleObjectsReturned: + return HttpResponseRedirect('/admin/accounts/all') + + except User.MultipleObjectsReturned: return HttpResponseRedirect('/admin/accounts/all') 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, request.FILES, instance=user) if form.is_valid(): user = form.save() @@ -59,27 +66,29 @@ def user_change(request, url): user.save() return HttpResponseRedirect('/admin/accounts/all') else: - form.fields['city'].widget.attrs['data-init-text'] = user.profile.city.name + if user.profile.city: + form.fields['city'].widget.attrs['data-init-text'] = user.profile.city.name else: 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} + 'about': profile.about, 'skype':profile.skype,'facebook':profile.facebook, 'linkedin':profile.linkedin, + 'twitter':profile.twitter, 'vk':profile.vk} form = UserForm(instance=user,initial=data) if user.profile.city: form.fields['city'].widget.attrs['data-init-text'] = user.profile.city.name - args = {} - args.update(csrf(request)) + context = {} + context.update(csrf(request)) - args['form'] = form - args['object'] = user + context['form'] = form + context['object'] = user - return render_to_response('user_change.html', args) + return render_to_response('user_change.html', context) def create_admin(request): if request.POST: diff --git a/accounts/admin_urls.py b/accounts/admin_urls.py index d4dc3cd3..225255e1 100644 --- a/accounts/admin_urls.py +++ b/accounts/admin_urls.py @@ -1,12 +1,13 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, url -from admin import UserListView +from admin import UserListView, EditUser urlpatterns = patterns('', #url(r'^registration/$', 'accounts.admin.registration'), #url(r'^create_admin/$', 'accounts.admin.create_admin'), #url(r'^create_md5user/$', 'accounts.admin.create_md5'), - url(r'^change/(.*)/$', 'accounts.admin.user_change'), + # url(r'^change/(?P.*)/$', EditUser.as_view()), + url(r'^change/(?P.*)/$', 'accounts.admin.user_change'), url(r'^all/$', UserListView.as_view()), url(r'^reset_password_email/$', 'accounts.admin.reset_password_email'), ) \ No newline at end of file diff --git a/accounts/forms.py b/accounts/forms.py index 9d7ceb1f..395ac037 100644 --- a/accounts/forms.py +++ b/accounts/forms.py @@ -474,4 +474,4 @@ class FeedFilterForm(forms.Form): if tg: res = ast.literal_eval(tg) return res - return tg \ No newline at end of file + return tg diff --git a/accounts/models.py b/accounts/models.py index 43125dcc..ce4e4b47 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -32,7 +32,8 @@ class UserManager(BaseUserManager): raise ValueError('Вы должни ввести электронную почту') user= self.model( - email = UserManager.normalize_email(email),first_name = first_name,last_name = last_name, + email = UserManager.normalize_email(email), + first_name = first_name,last_name = last_name, username = UserManager.normalize_email(email), is_staff=False, is_active=False, is_superuser=False, last_login=now, date_joined=now, **extra_fields @@ -42,7 +43,7 @@ class UserManager(BaseUserManager): user.save(using=self._db) return user - def create_social_user(self,username, first_name, last_name, password=None, **extra_fields): + def create_social_user(self, username, first_name, last_name, password=None, **extra_fields): now = timezone.now() # generate random password digits = random.sample(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'), 4) @@ -116,7 +117,7 @@ class User(AbstractBaseUser, PermissionsMixin): first_name = models.CharField(verbose_name='First name', max_length=255) last_name = models.CharField(verbose_name='Last name', max_length=255) rating = models.IntegerField(default=100)# добавить индекс в базе - url = models.SlugField(blank=True) + url = models.SlugField(blank=True)#, unique=True, null=True) # is_active = models.BooleanField(default=0) # СДЕЛАТЬ проверку на емейле is_staff = models.BooleanField(default=0) @@ -382,8 +383,10 @@ def calculate_rating(user): user_rating_fields = {'position': 5, 'company': 5, 'url': 10} profile_rating_fields = {'country': 5, 'city': 5, 'phone': 10, 'facebook': 5, 'twitter': 5, 'linkedin': 5, 'vk': 5, 'web_page': 10, 'avatar': 20, 'about': 15} - # доделать "Отметки на выставках, за каждую", "Подписка на рассылку", "Добавление фото, за каждую", "Добавление компании, за каждую опубликованную" - + ''' + TODO: доделать "Отметки на выставках, за каждую", "Подписка на рассылку", "Добавление фото, за каждую", + "Добавление компании, за каждую опубликованную" + ''' # base rating rating = 100 for key, value in user_rating_fields.iteritems(): diff --git a/accounts/urls.py b/accounts/urls.py index ffd93efa..2345511f 100644 --- a/accounts/urls.py +++ b/accounts/urls.py @@ -16,6 +16,7 @@ urlpatterns = patterns('', url(r'^profile/company/$', login_required(ProfileCompanyView.as_view())), url(r'^profile/settings/$', login_required(SettingsView.as_view())), url(r'^profile/calendar/remove/$', 'accounts.views.remove_from_calendar'), + url(r'^profile/calendar/export/$', 'core.views.download_workbook'), url(r'^profile/calendar/$', login_required(CalendarView.as_view())), url(r'^profile/feed/page/(?P\d+)/$', Feed.as_view()), url(r'^profile/feed/$', login_required(Feed.as_view())), @@ -28,6 +29,7 @@ urlpatterns = patterns('', url(r'^user/(?P.*)/events/(?P\d+)/$', UserView.as_view()), url(r'^user/(?P.*)/events/$', UserView.as_view()), url(r'^user/(?P.*)/$', UserView.as_view()), + url(r'^inactive-user/$', 'registration.backends.default.views.inactive_user_message'), #url(r'^profile/messages/(?P.*)/$', login_required(MessagesView.as_view())), #url(r'^profile/messages/$', login_required(MessagesView.as_view())), diff --git a/core/forms.py b/core/forms.py index baf0a04b..6244f97e 100644 --- a/core/forms.py +++ b/core/forms.py @@ -6,7 +6,8 @@ from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference from django.utils.translation import ugettext_lazy as _ from haystack.query import SearchQuerySet, EmptySearchQuerySet - +from hvad.forms import TranslatableModelForm +from models import Page class PlaceSearchForm(forms.Form): q = forms.CharField(label=_(u'Поиск'), required=False) @@ -45,3 +46,38 @@ class CallbackForm(forms.Form): def send(self): phone = self.cleaned_data['callback_phone'] send_mail(phone, phone, None, [settings.CALLBACK_EMAIL]) + + +# ------------------ Page Form ----------------------- + +from django.conf import settings +from django.forms import Textarea +from ckeditor.widgets import CKEditorWidget + + + +class PageForm(TranslatableModelForm): + # language = 'ru' + + class Meta: + model = Page + fields = ['url','title','h1','descriptions','keywords', 'body' ] + widgets = { + 'body':CKEditorWidget, + 'keywords':Textarea, + 'descriptions':Textarea, + } + def clean_url(self): + url = self.cleaned_data.get('url', None) + if url[0] == '/': + url = url[1:] + if url[-1] == '/': + url = url[:-1] + if ' ' in url: + url.replace(' ', '_') + return url + + + + + diff --git a/core/models.py b/core/models.py index dad86ae2..268a7009 100644 --- a/core/models.py +++ b/core/models.py @@ -1,12 +1,18 @@ # -*- coding: utf-8 -*- from django.contrib.syndication.views import Feed from django.shortcuts import get_object_or_404 +from django.db import models from exposition.models import Exposition +from settings.models import create_transl_fields from theme.models import Theme from country.models import Country from city.models import City +from hvad.models import TranslatableModel, TranslatedFields + +# ----------------------- RSS -------------------------- # + EXPO_ON_PAGE = 10 # nearest expositions at all @@ -85,4 +91,47 @@ class ThemeFeeds(Feed): return obj.main_title def items(self, obj): - return Exposition.enable.upcoming().filter(theme = obj)[:NUM_ITEMS_ON_PAGE] \ No newline at end of file + return Exposition.enable.upcoming().filter(theme = obj)[:NUM_ITEMS_ON_PAGE] + +# ------------------------ Page model --------------------------- # +from django.conf import settings +from django.core.urlresolvers import reverse + +class Page(TranslatableModel): + + url = models.SlugField(unique=True) + translations = TranslatedFields( + h1 = models.CharField(max_length=255), + body = models.TextField(), + # meta + title = models.CharField(max_length=255, blank=True), + descriptions = models.CharField(max_length=255, blank=True), + keywords = models.CharField(max_length=255, blank=True), + ) + created = models.DateTimeField(auto_now_add=True) + modified = models.DateTimeField(auto_now=True) + + def get_absolute_url(self): + return reverse('page_view', args=[self.url]) + + def save(self, *args, **kwargs): + super(Page,self).save(*args, **kwargs) + + all_field_names = list(self._translated_field_names) + clear_f_n = [] + for field_name in all_field_names: + if field_name not in ['master', 'master_id',u'id', 'language_code']: + clear_f_n.append(field_name) + field_items = {field_name:getattr(self, field_name) for field_name in clear_f_n} + + langs = [lan[0] for lan in settings.LANGUAGES] + for lang in langs: + if lang not in self.get_available_languages(): + self.translate(lang) + for field in clear_f_n: + setattr(self, field, field_items.get(field, '')) + obj = super(Page,self).save(*args, **kwargs) + return obj + + def __unicode__(self): + return self.url diff --git a/core/views.py b/core/views.py index 8683d1ab..9545b925 100644 --- a/core/views.py +++ b/core/views.py @@ -4,7 +4,8 @@ from country.models import Country from city.models import City from place_exposition.models import PlaceExposition from place_conference.models import PlaceConference -from django.views.generic import ListView, FormView +from django.views.generic import ListView, CreateView, DeleteView, UpdateView, DetailView +from django.core.urlresolvers import reverse_lazy from functions.views_help import split_params from django.utils.translation import ugettext as _ @@ -199,3 +200,83 @@ class PlacePhotoView(PlaceListView): context = super(PlacePhotoView, self).get_context_data(**kwargs) context['object'] = self.obj return context + + +# --------------------- Page views ------------------------ + +from forms import PageForm +from models import Page + +class NewPage(CreateView): + form_class= PageForm + template_name = 'new_page.html' + success_url = '/admin/page/all/' + + +class PageList(ListView): + paginate_by = 10 + template_name = 'page_admin_list.html' + model = Page + order = 'created' +from django import forms +from django.http import HttpResponseRedirect +class EditPage(UpdateView): + model = Page + template_name = 'new_page.html' + form_class = PageForm + slug_url_kwarg = 'url' + slug_field = 'url' + + def get_context_data(self, **kwargs): + context = super(EditPage,self).get_context_data(**kwargs) + context['request'] = self.request + return context + + def get_success_url(self): + return HttpResponseRedirect('/admin/page/all/') + +class DeletePage(DeleteView): + template_name = 'admin/page/page_confirm_delete.html' + model = Page + success_url = reverse_lazy('page_list') + slug_field = 'url' + slug_url_kwarg = 'url' + +class PageDetailed(DetailView): + model = Page + template_name = 'client/base_page.html' + slug_field = 'url' + slug_url_kwarg = 'url' + + + + + +# ------------ XLS Export ---------------- + +from django.http import HttpResponse +from .utils import queryset_to_workbook +from exposition.models import Exposition +from conference.models import Conference + +def download_workbook(request): + data = [(36539, 'expo'),(36602, 'expo'), (3033, 'conf'), (3053, 'conf')] + qs = [] + for obj in data: + if obj[1] == 'expo': + qs.append(Exposition.objects.get(id=obj[0])) + if obj[1] == 'conf': + qs.append(Conference.objects.get(id=obj[0])) + columns = ( + 'name', + 'country.name', + 'city.name', + 'place.name', + 'data_begin', + 'data_end') + + workbook = queryset_to_workbook(qs, columns) + response = HttpResponse(content_type='application/vnd.ms-excel') + response['Content-Disposition'] = 'attachment; filename="export.xls"' + workbook.save(response) + return response diff --git a/country/manager.py b/country/manager.py index fde5ca56..1d4b278e 100644 --- a/country/manager.py +++ b/country/manager.py @@ -7,13 +7,13 @@ from hvad.models import TranslationManager class CountryManager(TranslationManager): cache_time = 600 - + ''' def all(self): """ hack """ return super(TranslationManager, self).all().filter(translations__language_code=lang()).order_by('translations__name') - + ''' def safe_get(self, **kwargs): model = self.model try: diff --git a/expobanner/forms.py b/expobanner/forms.py index 64ef9f5a..82bfd39e 100644 --- a/expobanner/forms.py +++ b/expobanner/forms.py @@ -28,49 +28,13 @@ class BannerGroupUpdateForm(BannerCreateGroupForm): class BannerCreateForm(forms.ModelForm): verbose = u'Создать банер' - country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) - theme = forms.ChoiceField(label=u'Тематика', required=False, - choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) - city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) - tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) + #country = forms.ChoiceField(label=u'Страна', choices=[('', ' ')] + [(c.id, c.name) for c in Country.objects.all()], required=False) + #theme = forms.ChoiceField(label=u'Тематика', required=False, + # choices=[('', ' ')] + [(item.id, item.name) for item in Theme.objects.language().all()]) + #city = forms.CharField(label=u'Город', widget=forms.HiddenInput(), required=False) + #tag = forms.CharField(label=u'Тег', widget=forms.HiddenInput(), required=False) class Meta: model = Banner - exclude = ['created_at', 'updated_at', 'often', 'paid'] - - def clean_theme(self): - theme = self.cleaned_data['theme'] - if not theme: - return None - try: - return Theme.objects.filter(id=theme) - except Theme.DoesNotExist: - return None - - def clean_country(self): - country = self.cleaned_data['country'] - if not country: - return None - try: - return Country.objects.get(id=country) - except Country.DoesNotExist: - return None - - def clean_tag(self): - tag = self.cleaned_data['tag'] - if not tag: - return None - try: - return Tag.objects.get(id=tag) - except Tag.DoesNotExist: - return None - - def clean_city(self): - city = self.cleaned_data['city'] - if not city: - return None - try: - return City.objects.get(id=city) - except City.DoesNotExist: - return None \ No newline at end of file + exclude = ['created_at', 'updated_at', 'often', 'paid'] \ No newline at end of file diff --git a/expobanner/managers.py b/expobanner/managers.py index af87215b..e4cebd65 100644 --- a/expobanner/managers.py +++ b/expobanner/managers.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -* +from datetime import date from random import choice, shuffle from django.db import models +from django.db.models import Q from django.core.cache import cache @@ -26,7 +28,31 @@ class BannerGroupCached(models.Manager): key = 'banner_group_all' result = cache.get(key) if not result: - result = list(self.filter()) + result = list(self.filter(public=True)) cache.set(key, result, 90) return result + def group_banners(self): + key = 'banner_group_banners' + result = cache.get(key) + if not result: + groups = self.all() + today = date.today() + result = {} + for group in groups: + result[group.slug] = list(group.banners.prefetch_related('urls', 'theme', 'country')\ + .filter(public=True, fr__lte=today)\ + .filter(Q(to__gte=today) | Q(to__isnull=True)).extra({})) + cache.set(key, result, 70) + + return result + + +class URLCached(models.Manager): + def all(self): + key = 'banner_url_all' + result = cache.get(key) + if not result: + result = list(self.filter(public=True)) + cache.set(key, result, 150) + return result \ No newline at end of file diff --git a/expobanner/models.py b/expobanner/models.py index 7914ae58..a016785d 100644 --- a/expobanner/models.py +++ b/expobanner/models.py @@ -1,13 +1,13 @@ # -*- coding: utf-8 -*- import hashlib from datetime import datetime, date - from django.db import models from django.utils.translation import ugettext_lazy as _ from django.conf import settings from django.contrib.sites.models import Site - -from .managers import BiasedManager, BannerGroupCached +from .managers import BiasedManager, BannerGroupCached, URLCached +from theme.models import Theme +from country.models import Country class URL(models.Model): @@ -20,6 +20,9 @@ class URL(models.Model): created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) + objects = models.Manager() + cached = URLCached() + def __unicode__(self): return self.title @@ -42,6 +45,8 @@ class BannerGroup (models.Model): public = models.BooleanField(verbose_name=u'Активная', default=True) created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) + + objects = models.Manager() cached = BannerGroupCached() def size(self): @@ -68,6 +73,11 @@ class Banner(models.Model): text = models.TextField(verbose_name=u'Текст', blank=True, null=True) img = models.FileField(verbose_name=u'Картинка', upload_to='expo_upload', blank=True, null=True) url = models.CharField(verbose_name=u'URL', max_length=1024) + fr = models.DateField(default=date.today()) + to = models.DateField(blank=True, null=True) + + theme = models.ManyToManyField(Theme, blank=True, null=True, verbose_name=u'Тематика') + country = models.ManyToManyField(Country, blank=True, null=True, verbose_name=u'Страна') sort = models.PositiveSmallIntegerField(verbose_name=u'Сорт', default=500) @@ -75,7 +85,8 @@ class Banner(models.Model): often = models.PositiveSmallIntegerField( verbose_name=_('Often'), help_text=_('A ten will display 10 times more often that a one.'), - choices=[[i, i] for i in range(11)] + choices=[[i, i] for i in range(11)], + default=1 ) urls = models.ManyToManyField(URL, related_name='url_banners', verbose_name=_('URLs'), null=True, blank=True) @@ -88,12 +99,6 @@ class Banner(models.Model): created_at = models.DateTimeField(verbose_name=_('Created At'), auto_now_add=True) updated_at = models.DateTimeField(verbose_name=_('Updated At'), auto_now=True) - theme = models.ForeignKey('theme.Theme', blank=True, null=True, verbose_name=u'Тематика') - tag = models.ForeignKey('theme.Tag', blank=True, null=True, verbose_name=u'Тег') - country = models.ForeignKey('country.Country', blank=True, null=True, verbose_name=u'Страна') - city = models.ForeignKey('city.City', blank=True, null=True, verbose_name=u'Город') - - def get_admin_url(self): return '/admin/expobanners/banners/banner/%d/edit/'%self.id diff --git a/expobanner/views.py b/expobanner/views.py index 903408ea..ebe8f182 100644 --- a/expobanner/views.py +++ b/expobanner/views.py @@ -1,8 +1,10 @@ # -*- coding: utf-8 -*- import json +import re +import random from django.http import HttpResponse from django.shortcuts import redirect, get_object_or_404 -from .models import Banner, BannerGroup +from .models import Banner, BannerGroup, URL def click(request, banner_id, key): @@ -25,22 +27,100 @@ def get_client_ip(request): ip = request.META.get('REMOTE_ADDR') return ip +def get_by_sort(banner_list): + max_sort = 0 + for banner in banner_list: + sort = banner.sort + if sort > max_sort: + max_sort = sort + result = [banner for banner in banner_list if banner.sort == max_sort] + return result + +from django.db import connection +def get_banner_by_params(banners_list, urls, params): + print('START. NUMBER of queries = %d'%len(connection.queries)) + good_banners = [] + + for banner in banners_list: + print('-------------------------') + print('number of queries = %d'%len(connection.queries)) + print(banner) + # check by theme + banner_theme_ids = [str(theme.id) for theme in banner.theme.all()] + print('number of queries = %d'%len(connection.queries)) + + if banner_theme_ids: + if params.get('theme'): + theme = params['theme'] + if theme in banner_theme_ids: + good_banners.append(banner) + continue + # check by country + banner_country_ids = [str(country.id) for country in banner.country.all()] + print('number of queries = %d'%len(connection.queries)) + if banner_country_ids: + if params.get('country'): + + country = params['country'] + if country in banner_country_ids: + good_banners.append(banner) + continue + + # check by url + if urls: + banner_urls = banner.urls.all() + print('number of queries = %d'%len(connection.queries)) + + if banner_urls: + + banner_urls = set(banner_urls) + common_urls = set(urls).intersection(banner_urls) + + if common_urls: + good_banners.append(banner) + continue + print('-------------------------') + good_banners = get_by_sort(good_banners) + + print('END. NUMBER of queries = %d'%len(connection.queries)) + + + if good_banners: + return random.choice(good_banners) + return [] + def get_banners(request): + # get urls by current url url = request.GET.get('url', '/') - theme = request.GET.get('theme') - country = request.GET.get('country') - city = request.GET.get('city') - tag = request.GET.get('tag') - ip = get_client_ip(request) - params = {'url': url, - 'theme': theme, - 'tag': tag, - 'country': country, - 'city': city, - 'ip': ip} - b = Banner.objects.get(id=1) - result = [{'url': b.url, 'id': 'expo_b_%d'%b.id, 'is_html': b.html, - 'is_flash': b.flash, 'is_img': True, 'html': b.text, 'img': b.img.url}] + urls = URL.cached.all() + good_urls = [] + for u in urls: + if u.regex: + url_re = re.compile(u.url) + if url_re.findall(url): + good_urls.append(u) + elif url == u.url: + good_urls.append(u) + # fill parameters dict + params = {'theme': request.GET.get('theme'), + 'tag': request.GET.get('tag'), + 'country': request.GET.get('country'), + 'city': request.GET.get('city'), + 'ip': get_client_ip(request)} + + group_banners = BannerGroup.cached.group_banners() + result = [] + for group, banners in group_banners.iteritems(): + banner = get_banner_by_params(banners, good_urls, params) + result.append({'id': group, + 'url': banner.url, + 'is_html': banner.html, + 'is_flash': banner.flash, + 'is_img': True, + 'html': banner.text, + 'img': banner.img.url + }) + return HttpResponse(json.dumps(result, indent=4), content_type='application/json') diff --git a/exposition/search_indexes.py b/exposition/search_indexes.py index 639a9c7e..0a427eb7 100644 --- a/exposition/search_indexes.py +++ b/exposition/search_indexes.py @@ -19,9 +19,9 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable, ExpoSearchMixin): content_auto = indexes.EdgeNgramField() form_name = indexes.CharField() # translated fields - name_en = indexes.CharField() + name_en = indexes.CharField() name_ru = indexes.CharField() - catalog_name_en = indexes.CharField() + catalog_name_en = indexes.CharField() catalog_name_ru = indexes.CharField() def prepare_form_name(self, obj): diff --git a/functions/models_methods.py b/functions/models_methods.py index 486fb71e..35121ea9 100644 --- a/functions/models_methods.py +++ b/functions/models_methods.py @@ -11,13 +11,13 @@ class ExpoManager(TranslationManager): def upcoming(self): return self.language().select_related('country', 'city', 'place').filter(data_begin__gte=datetime.datetime.now().date()).order_by('data_begin') - + """ def all(self, lang=None): if lang: return super(ExpoManager, self).language(lang).all().order_by('name') else: return super(ExpoManager, self).language(get_language()).all().order_by('name') - + """ def safe_get(self, **kwargs): model = self.model try: diff --git a/functions/pipeline.py b/functions/pipeline.py index 1d167830..d7260b00 100644 --- a/functions/pipeline.py +++ b/functions/pipeline.py @@ -1,41 +1,97 @@ from accounts.models import User +import random +import string +def random_pass(): + digits = random.sample(('0', '1', '2', '3', '4', '5', '6', '7', '8', '9'), 4) + chars = random.sample(string.lowercase[:], 4) + password = chars + digits + random.shuffle(password) + return ''.join(password) -def load_user(details, response, uid, *args, **kwargs): - if details.get('email'): - username = details.get('email') - else: - username = str(uid) - user = User.objects.safe_get(username=username) +def load_user(strategy, details, response, uid, *args, **kwargs): + user = None + if details.get('email'): + email = details.get('email') + user = User.objects.safe_get(email=email) return {'user': user, 'is_new': False} +from django.contrib.sites.models import Site, RequestSite +from registration.models import RegistrationProfile + def create_user(strategy, details, response, uid, user=None, *args, **kwargs): if user: return {'user': user, 'is_new': False} else: + request = strategy.request + if Site._meta.installed: + site = Site.objects.get_current() + else: + site = RequestSite(request) + new_user = RegistrationProfile.objects.create_inactive_user(details['first_name'], details['last_name'], details['email'], + random_pass(), site or 1) + signals.user_registered.send(sender=User, user=new_user, request=request) + #user = User.objects.create_social_user(username, details['first_name'], details['last_name']) + return {'user': new_user, 'is_new': True} - if details.get('email'): - username = details.get('email') + +from django.shortcuts import redirect +from social.pipeline.partial import partial +from registration import signals + +@partial +def require_email(strategy, details, user=None, is_new=False, *args, **kwargs): + if user and user.email: + return + elif is_new and not details.get('email'): + email = strategy.request_data().get('email') + if email: + details['email'] = email else: - username = str(uid) + strategy.request.session['new_email'] = True + return redirect('acquire_email') + + + - user = User.objects.create_social_user(username, details['first_name'], details['last_name']) - return {'user': user, 'is_new': True} + + +from django.core import signing +from django.core.mail import EmailMultiAlternatives +from django.conf import settings +from django.core.urlresolvers import reverse + +def SendVerificationEmail(strategy, backend, code): """ - if details.get('email'): - user = User.objects.safe_get(email=details['email']) - if user: - return {'user': user, 'is_new': False} - else: - user = User.objects.create_user(email=details['email'], first_name=details['first_name'], - last_name=details['last_name'], password='1q2w3e4r', is_active=True) + Send an email with an embedded verification code and the necessary details to restore the required session + elements to complete the verification and sign-in, regardless of what browser the user completes the + verification from. + """ + signature = signing.dumps({"session_key": strategy.session.session_key, "email": code.email}, + key=settings.EMAIL_SECRET_KEY) + verifyURL = "{0}?verification_code={1}&signature={2}".format( + reverse('social:complete', args=(backend.name,)), + code.code, signature) + verifyURL = strategy.request.build_absolute_uri(verifyURL) - return {'user': user, 'is_new': True} - else: - return None - """ \ No newline at end of file + emailHTML = ''# Include your function that returns an html string here + emailText = """Welcome to Expomap.ru! +In order to login with your new user account, you need to verify your email address with us. +Please click on this link to continue registration. +""".format(verifyURL=verifyURL) + + kwargs = { + "subject": "Verify Your Account", + "body": emailText, + "from_email": settings.CALLBACK_EMAIL, + "to": [code.email], + } + + email = EmailMultiAlternatives(**kwargs) + email.attach_alternative(emailHTML, "text/html") + email.send() \ No newline at end of file diff --git a/functions/search_forms.py b/functions/search_forms.py index f65fc334..557f356f 100644 --- a/functions/search_forms.py +++ b/functions/search_forms.py @@ -239,7 +239,6 @@ class ExpositionSearchForm(AbstactSearchForm): 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.language().all()], diff --git a/import_xls/utils.py b/import_xls/utils.py index 8efe455c..018bc924 100644 --- a/import_xls/utils.py +++ b/import_xls/utils.py @@ -65,12 +65,12 @@ def to_country(value): 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.id except IndexError: print('---------city error------------') @@ -173,7 +173,6 @@ def save_logo(obj, path): full_path = settings.MEDIA_ROOT + logo_path - try: alt_name = get_alternative_filename(full_path, file_name) except UnicodeEncodeError: diff --git a/meta/admin_urls.py b/meta/admin_urls.py index f2062f38..a545ff76 100644 --- a/meta/admin_urls.py +++ b/meta/admin_urls.py @@ -1,9 +1,14 @@ # -*- coding: utf-8 -*- from django.conf.urls import patterns, include, url from admin import MetaListView, MetaView +from .views import CreateSeoText, SeoTextList, EditSeoText, DeleteSeoText urlpatterns = patterns('conference.admin', + url(r'^seo/new/$', CreateSeoText.as_view(), name='seo_new'), + url(r'^seo/all/$', SeoTextList.as_view(), name='seo_all'), + url(r'^seo/edit/(?P\d{1,5})/$', EditSeoText.as_view(), name='seo_edit'), + url(r'^seo/delete/(?P\d{1,5})/$', DeleteSeoText.as_view(), name='seo_delete'), url(r'^all/$', MetaListView.as_view()), #url(r'^change/(?P.*)/$', 'conference_change'), url(r'^(?P.*)/$', MetaView.as_view()), diff --git a/meta/forms.py b/meta/forms.py index ee8983cc..eb93f28a 100644 --- a/meta/forms.py +++ b/meta/forms.py @@ -45,4 +45,16 @@ class MetaForm(forms.Form): meta.save() class MetaFilterForm(AdminFilterForm): - model = MetaSetting \ No newline at end of file + model = MetaSetting + + +from .models import SeoText +from ckeditor.widgets import CKEditorWidget +from hvad.forms import TranslatableModelForm + +class SeoTextForm(TranslatableModelForm): + + class Meta: + model = SeoText + fields = ['url', 'title', 'body'] + widgets = {'body':CKEditorWidget} \ No newline at end of file diff --git a/meta/models.py b/meta/models.py index 79d02800..c3be90d8 100644 --- a/meta/models.py +++ b/meta/models.py @@ -115,6 +115,7 @@ class MetaSetting(TranslatableModel): post_save.connect(post_save_handler, sender=MetaSetting) + # SEO - tests # from django.db import models @@ -128,7 +129,8 @@ class SeoTextManager(TranslationManager): cache_time = 120 def cache_get(self, *args, **kwargs): - url = kwargs.get('url',None) + # ПЕРЕРОБИТИ + url = kwargs.get('url') lang = kwargs.get('lang')[:2] or translation.get_language()[:2] key = 'seo_text_cache' result = cache.get(key) @@ -176,4 +178,4 @@ class SeoText(TranslatableModel): return SeoText def __unicode__(self): - return self.url \ No newline at end of file + return self.url diff --git a/meta/views.py b/meta/views.py index c8146091..28d30eba 100644 --- a/meta/views.py +++ b/meta/views.py @@ -187,4 +187,49 @@ class MetadataMixin(object): site_name=self.get_meta_site_name(context=context), ) - return context \ No newline at end of file + return context + +from django.views.generic import CreateView, UpdateView, DeleteView, ListView +from .models import SeoText +from .forms import SeoTextForm + + +class CreateSeoText(CreateView): + form_class = SeoTextForm + model = SeoText + template_name = "admin/meta/create_seo_text.html" + success_url = '/admin/meta/seo/all/' + + +class SeoTextList(ListView): + model = SeoText + template_name = "admin/meta/seo_admin_list.html" + + +class EditSeoText(UpdateView): + form_class = SeoTextForm + model = SeoText + template_name = "admin/meta/create_seo_text.html" + + +class DeleteSeoText(DeleteView): + model = SeoText + template_name = "admin/meta/seo_confirm_delete.html" + success_url = '/admin/meta/seo/all/' + + + + + + + + + + + + + + + + + diff --git a/proj/admin_urls.py b/proj/admin_urls.py index 0e66313d..47bbfeaf 100644 --- a/proj/admin_urls.py +++ b/proj/admin_urls.py @@ -12,12 +12,14 @@ urlpatterns = required( url(r'^$', AdminIndex.as_view()), url(r'^', include('import_xls.admin_urls')), url(r'^accounts/', include('accounts.admin_urls')), + url(r'page/', include('core.admin_urls')), url(r'^article/', include('article.admin_urls')), url(r'^photogallery/', include('photologue.admin_urls')), url(r'^city/', include('city.admin_urls')), url(r'^company/', include('company.admin_urls')), url(r'^conference/', include('conference.admin_urls')), url(r'^country/', include('country.admin_urls')), + url(r'^expobanners/', include('expobanner.admin_urls')), url(r'^exposition/', include('exposition.admin_urls')), url(r'^news/', include('news.admin_urls')), url(r'^organiser/', include('organiser.admin_urls')), diff --git a/proj/settings.py b/proj/settings.py index 4a8d8883..ed02b25d 100644 --- a/proj/settings.py +++ b/proj/settings.py @@ -42,7 +42,7 @@ CACHES = { # Hosts/domain names that are valid for this site; required if DEBUG is False # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts -ALLOWED_HOSTS = ['hit.expomap.ru', '195.66.79.152', '195.66.79.145', 'expomap.ru'] +ALLOWED_HOSTS = ['hit.expomap.ru', '195.66.79.152', '195.66.79.145', 'expomap.ru', '195.66.79.148'] # Local time zone for this installation. Choices can be found here: # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name @@ -108,7 +108,7 @@ STATIC_URL = '/static/' STATICFILES_FINDERS = ( 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', -# 'django.contrib.staticfiles.finders.DefaultStorageFinder', + #'django.contrib.staticfiles.finders.DefaultStorageFinder', ) # Make this unique, and don't share it with anybody. @@ -173,6 +173,7 @@ TEMPLATE_DIRS = ( os.path.join(SITE_ROOT, 'templates/admin/organiser'), os.path.join(SITE_ROOT, 'templates/admin/place_conference'), os.path.join(SITE_ROOT, 'templates/admin/place_exposition'), + os.path.join(SITE_ROOT, 'templates/admin/page'), os.path.join(SITE_ROOT, 'templates/admin/photoreport'), os.path.join(SITE_ROOT, 'templates/admin/settings'), os.path.join(SITE_ROOT, 'templates/admin/seminar'), @@ -198,12 +199,13 @@ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'localhost' EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' -EMAIL_USE_TLS = False +EMAIL_USE_TLS = True EMAIL_PORT = 25 DEFAULT_FROM_EMAIL = "expomap.ru" AUTHENTICATION_BACKENDS = ( + 'social.backends.open_id.OpenIdAuth', 'social.backends.vk.VKOAuth2', 'social.backends.facebook.FacebookOAuth2', 'social.backends.twitter.TwitterOAuth', @@ -216,16 +218,29 @@ AUTHENTICATION_BACKENDS = ( SOCIAL_AUTH_LOGIN_URL = '/' SOCIAL_AUTH_USER_MODEL = 'accounts.User' -#SOCIAL_AUTH_UID_LENGTH = -#SOCIAL_AUTH_NONCE_SERVER_URL_LENGTH = -#SOCIAL_AUTH_ASSOCIATION_SERVER_URL_LENGTH = -#SOCIAL_AUTH_FORCE_EMAIL_VALIDATION = True +SOCIAL_AUTH_LOGIN_REDIRECT_URL = '/logged-in/' +# The user will be redirected to this URL when a social account is disconnected +SOCIAL_AUTH_INACTIVE_USER_URL = '/inactive-user/' +# #Used to redirect the user once the auth process ended successfully. The value of ?next=/foo is used if it was present +# SOCIAL_AUTH_LOGIN_ERROR_URL = '/login-error/' +# #URL where the user will be redirected in case of an error +# SOCIAL_AUTH_LOGIN_URL = '/login-url/' +# #Is used as a fallback for LOGIN_ERROR_URL +# SOCIAL_AUTH_NEW_USER_REDIRECT_URL = '/new-users-redirect-url/' +# # Used to redirect new registered users, will be used in place of SOCIAL_AUTH_LOGIN_REDIRECT_URL if defined. +# Note that ?next=/foo is appended if present, if you want new users to go to next, you’ll need to do it yourself. +# SOCIAL_AUTH_NEW_ASSOCIATION_REDIRECT_URL = '/new-association-redirect-url/' +# # Like SOCIAL_AUTH_NEW_USER_REDIRECT_URL but for new associated accounts (user is already logged in). +# Used in place of SOCIAL_AUTH_LOGIN_REDIRECT_URL +# SOCIAL_AUTH_DISCONNECT_REDIRECT_URL = '/account-disconnected-redirect-url/' + +# Inactive users can be redirected to this URL when trying to authenticate. +# SOCIAL_AUTH_UID_LENGTH = +# SOCIAL_AUTH_NONCE_SERVER_URL_LENGTH = +# SOCIAL_AUTH_ASSOCIATION_SERVER_URL_LENGTH = +# SOCIAL_AUTH_FORCE_EMAIL_VALIDATION = True SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True -#SOCIAL_AUTH_STORAGE = 'social.apps.django_app.me.models.DjangoStorage' - -SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True - SOCIAL_AUTH_PIPELINE = ( 'social.pipeline.social_auth.social_details', @@ -283,6 +298,7 @@ SOCIAL_AUTH_LINKEDIN_SECRET = 'GvM2xQCNADaBfiMy' SOCIAL_AUTH_LINKEDIN_SCOPE = ['email'] + INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', @@ -302,6 +318,7 @@ INSTALLED_APPS = ( 'core', 'country', 'directories', + 'expobanner', 'exposition', 'file', 'import_xls', @@ -335,7 +352,8 @@ INSTALLED_APPS = ( 'pymorphy', # ?? 'password_reset', # reset password 'django_crontab', # crons - 'social.apps.django_app.default', # social auth, + 'social.apps.django_app.default', # social auth + 'core', ) @@ -383,7 +401,6 @@ LOGGING = { } } - CRONJOBS = [ ('0 */1 * * *', 'django.core.management.call_command', ['update_index conference --age=1']), ('0 */1 * * *', 'django.core.management.call_command', ['update_index exposition --age=1']), @@ -478,23 +495,4 @@ if DEBUG: # 'INTERCEPT_REDIRECTS': False, #} -""" - -LOGGING = { - 'version': 1, - 'disable_existing_loggers': True, - 'handlers': { - 'file': { - 'level': 'DEBUG', - 'class': 'logging.FileHandler', - 'filename': '/var/log/django_debug.log', - }, - }, - 'loggers': { - 'django.request': { - 'handlers': ['file'], - 'level': 'DEBUG', - 'propagate': True, - }, - }, -} \ No newline at end of file +""" \ No newline at end of file diff --git a/proj/urls.py b/proj/urls.py index f0f15a91..edebf6eb 100644 --- a/proj/urls.py +++ b/proj/urls.py @@ -45,6 +45,7 @@ urlpatterns = patterns('', url(r'^theme/', include('theme.urls')), url(r'^places/', include('place_exposition.urls')), url(r'^translators/', include('translator.urls')), + url(r'^expo-b/', include('expobanner.urls')), url(r'^', include('accounts.urls')), url(r'^', include('exposition.urls')), url(r'^', include('settings.conference_old_urls')), # conference redirects from old version diff --git a/proj/views.py b/proj/views.py index c5cb918d..0db0e5bd 100644 --- a/proj/views.py +++ b/proj/views.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- from django.core.context_processors import csrf -from django.shortcuts import render_to_response +from django.shortcuts import render_to_response from django.template import RequestContext from django.views.generic import TemplateView from django.conf import settings @@ -14,24 +14,53 @@ from functions.forms import ThemeSearch, PlaceSearch from functions.search_forms import EventSearchForm, ExpositionSearchForm from functions.custom_views import ExpoListView -from accounts.forms import RegistrationCompleteForm +from accounts.forms import RegistrationCompleteForm, SocialRegistrationCompleteForm +from meta.models import SeoText +from django.utils.translation import get_language + + +def clear_slashes(str_): + if str_[0] == r'/': + str_ = str_[1:] + if str_[-1] == r'/': + str_ = str_[:-1] + return str_ + +def add_seo(request): + url = request.path + lang = get_language() + try: + seo_text = SeoText.objects.cache_get(url=url, lang=lang) + except SeoText.DoesNotExist: + try: + seo_text = SeoText.objects.cache_get(url=url[:-1], lang=lang) + except SeoText.DoesNotExist: + seo_text = None + return seo_text def expo_context(request): banners_themes = [24, 34, 4] - banner_tags = [141, 142, 143, 156, 206, 231, 232, 390, 391, 400, 457, 500, 536, 537, 539, 457, 500, 686, 715, 765, 766, 857, 927, 964, 971, 972, 987, 1009, 1010, 1021, 2508, 2509, 2516, 2518, 2536, 2568, 2583, 2585, 3811, 3940, 4130, 4192, 4236, 4512, 4841, 5353, 5532, 5854, 106, 107, 195, 380, 930, 931, 932, 3845, 3846, 3863, 3873, 4141, 4142, 4343, 4344, 4347, 211, 212, 277, 631] + banner_tags = [141, 142, 143, 156, 206, 231, 232, 390, 391, 400, 457, 500, 536, 537, 539, 457, 500, 686, 715, 765, + 766, 857, 927, 964, 971, 972, 987, 1009, 1010, 1021, 2508, 2509, 2516, 2518, 2536, 2568, 2583, 2585, + 3811, 3940, 4130, 4192, 4236, 4512, 4841, 5353, 5532, 5854, 106, 107, 195, 380, 930, 931, 932, 3845, + 3846, 3863, 3873, 4141, 4142, 4343, 4344, 4347, 211, 212, 277, 631] cont = {'theme_search_form': ThemeSearch(), 'expo_catalog': Exposition.catalog, 'book_aid': settings.BOOKING_AID, 'blogs': Article.objects.main_page_blogs(), 'news_list': Article.objects.main_page_news(), 'sng_countries': settings.SNG_COUNTRIES, - 'banner_themes' : banners_themes, 'banner_tags' : banner_tags + 'banner_themes': banners_themes, 'banner_tags': banner_tags, 'seo_text': add_seo(request) } user = request.user if not user.is_anonymous() and not user.url: - cont.update({'reg_complete': RegistrationCompleteForm(instance=user)}) + if not user.email: + cont.update({'reg_complete': SocialRegistrationCompleteForm(instance=user)}) + else: + cont.update({'reg_complete': RegistrationCompleteForm(instance=user)}) if not request.GET: cont.update({'search_form': ExpositionSearchForm()}) return cont + def error404(request): context = {} expo_themes = Theme.active.expo_themes_with_count() @@ -41,7 +70,8 @@ def error404(request): response.status_code = 404 return response -class MainPageView(JitterCacheMixin,TemplateView): + +class MainPageView(JitterCacheMixin, TemplateView): cache_range = settings.CACHE_RANGE template_name = 'index.html' @@ -63,5 +93,6 @@ class MainPageView(JitterCacheMixin,TemplateView): class AdvertisingView(TemplateView): template_name = 'simple_pages/advertising.html' + class AboutView(TemplateView): - template_name = 'simple_pages/about.html' \ No newline at end of file + template_name = 'simple_pages/about.html' diff --git a/registration/backends/default/views.py b/registration/backends/default/views.py index 29721193..667ea2a3 100644 --- a/registration/backends/default/views.py +++ b/registration/backends/default/views.py @@ -8,7 +8,7 @@ from registration import signals from registration.models import RegistrationProfile from registration.views import ActivationView as BaseActivationView from registration.views import RegistrationView as BaseRegistrationView - +from django.views.generic import View import json @@ -150,7 +150,7 @@ from django.http import HttpResponse, HttpResponseRedirect from accounts.models import User from registration.forms import RegistrationFormUniqueEmail -from django.contrib.auth import login, logout +from django.contrib.auth import login, logout, authenticate from django.views.decorators.debug import sensitive_post_parameters from django.views.decorators.cache import never_cache @@ -248,18 +248,29 @@ def LoginView(request): else: HttpResponseRedirect('/') -from accounts.forms import RegistrationCompleteForm, RecoveryForm -from django.shortcuts import render +from accounts.forms import RegistrationCompleteForm, RecoveryForm, SocialRegistrationCompleteForm +from social.apps.django_app.default.models import UserSocialAuth def complete_registration(request): if request.is_ajax(): response = {'success': False} - form = RegistrationCompleteForm(request.POST, instance=request.user) + if request.POST.get('email'): + form = SocialRegistrationCompleteForm(request.POST, instance=request.user) + else: + form = RegistrationCompleteForm(request.POST, instance=request.user) if form.is_valid(): user = form.save() - response['success']=True - response['redirect'] = user.get_permanent_url() + if user != request.user: + try: + social = UserSocialAuth.objects.get(user=request.user) + uid, provider = social.uid, social.provider + User.objects.get(id = request.user.id).delete() + user.social_auth.create(uid=uid, provider=provider) + except UserSocialAuth.DoesNotExist: + pass + response['success']= True + response['redirect'] = '/' else: response['errors'] = form.errors return HttpResponse(json.dumps(response), content_type='application/json') @@ -267,6 +278,9 @@ def complete_registration(request): else: return HttpResponse('not ajax') +from django.shortcuts import render + + def acquire_email(request, template_name="registration/acquire_email.html"): """ Request email for the create user flow for logins that don't specify their email address. @@ -275,6 +289,11 @@ def acquire_email(request, template_name="registration/acquire_email.html"): return render(request, template_name, {"backend": backend}) +def inactive_user_message(request): + return render(request, 'registration/social_registration_complete.html') + + + def pswd_recovery(request): #if request.is_ajax(): response = {'success': False} diff --git a/settings/management/commands/do_inflect.py b/settings/management/commands/do_inflect.py index 601a69a3..c226f08a 100644 --- a/settings/management/commands/do_inflect.py +++ b/settings/management/commands/do_inflect.py @@ -8,7 +8,7 @@ from city.models import City CITIES = settings.MEDIA_ROOT+'/import/cities_inflect.xls' TAGS = settings.MEDIA_ROOT+'/import/tags_inflect.xls' - +import inspect, os class Command(BaseCommand): def handle(self, *args, **options): diff --git a/settings/redirect_views.py b/settings/redirect_views.py index 74eccd85..67df53d2 100644 --- a/settings/redirect_views.py +++ b/settings/redirect_views.py @@ -131,11 +131,9 @@ class Country_or_City(object): result = 'city/%s'%obj.url return {key: result} - - old_params = {'city': CityRedirect, 'country': CountryRedirect, 'theme': ThemeRedirect, 'tag': TagRedirect, 'event': EventRedirect, 'company': Company, 'article': ArticleRedirect, 'user': UserRedirect, - 'page': PageRedirect, 'news_p': News_p, 'country_or_city': Country_or_City} + 'page': PageRedirect, 'news_p': News_p} def old_redirect(request, *args, **kwargs): diff --git a/templates/admin/accounts/user_change.html b/templates/admin/accounts/user_change.html index f7b40762..cff1f51f 100644 --- a/templates/admin/accounts/user_change.html +++ b/templates/admin/accounts/user_change.html @@ -1,4 +1,4 @@ -{% extends 'base.html' %} + {% extends 'base.html' %} {% load static %} {% block scripts %} diff --git a/templates/admin/expobanner/default_form.html b/templates/admin/expobanner/default_form.html index 30c72263..50d696c0 100644 --- a/templates/admin/expobanner/default_form.html +++ b/templates/admin/expobanner/default_form.html @@ -6,6 +6,19 @@ {% endblock %} diff --git a/templates/admin/import templates/import.html b/templates/admin/import templates/import.html index a6de3a3f..c67a3cf0 100644 --- a/templates/admin/import templates/import.html +++ b/templates/admin/import templates/import.html @@ -62,26 +62,6 @@ {% endfor %} {% endif %} - {% if import_errors %} -
- - - - - - - - - {% for error in import_errors %} - - - - - {% endfor %} - -
СобытиеОшибка
{{ error.0 }}{{ error.1 }}
-
- {% endif %} - {% endblock %} \ No newline at end of file diff --git a/templates/admin/includes/admin_nav.html b/templates/admin/includes/admin_nav.html index 7f1ec5ed..9f33389b 100644 --- a/templates/admin/includes/admin_nav.html +++ b/templates/admin/includes/admin_nav.html @@ -105,6 +105,13 @@ + + diff --git a/templates/admin/translator/translator_list.html b/templates/admin/translator/translator_list.html index 54e2a8e5..0751ed35 100644 --- a/templates/admin/translator/translator_list.html +++ b/templates/admin/translator/translator_list.html @@ -40,10 +40,13 @@ {{ item.profile.country.name }} - + Изменить + + Удалить + diff --git a/templates/client/base_catalog.html b/templates/client/base_catalog.html index 47a3ad79..64ae5440 100644 --- a/templates/client/base_catalog.html +++ b/templates/client/base_catalog.html @@ -98,12 +98,10 @@ {% endblock %} - {% block content_text %} - {% comment %} - {% with filter=filter %} - {% include 'includes/event_list_description.html' %} - {% endwith %} - {% endcomment %} + {% block seo_text_ %} + {% if seo_text %} + {% include 'client/includes/seo_text.html' with object=seo_text %} + {% endif %} {% endblock %} {% endblock %} diff --git a/templates/client/blank.html b/templates/client/blank.html index 169d8388..5c14ac22 100644 --- a/templates/client/blank.html +++ b/templates/client/blank.html @@ -112,6 +112,20 @@ This template include basic anf main styles and js files, ga('create', 'UA-3151423-1', 'auto'); ga('send', 'pageview'); + + @@ -247,14 +261,16 @@ This template include basic anf main styles and js files, {% endif %} {% endblock %} {# if user doesnt have url- show form #} - + {% if 'partial_pipeline' not in request.session %} + {% include 'client/popups/acquire_email.html' %} + {% endif %} {% if not request.user.is_anonymous %} {% if not request.user.url %} {% include 'client/popups/user_information.html' with form=reg_complete %} {% if request.GET.debug == '1' %} {% else %} - + {% endif %} {% endif %} {% endif %} diff --git a/templates/client/includes/header.html b/templates/client/includes/header.html index a8487e9b..a58bb786 100644 --- a/templates/client/includes/header.html +++ b/templates/client/includes/header.html @@ -37,6 +37,7 @@ {% endfor %} {% if user.is_staff %}
  • admin
  • +
  • TEST
  • {% endif %} diff --git a/templates/client/popups/user_information.html b/templates/client/popups/user_information.html index 4d73e42c..d2b21c2c 100644 --- a/templates/client/popups/user_information.html +++ b/templates/client/popups/user_information.html @@ -10,79 +10,90 @@
    {% csrf_token %}
      -
    • -
      -
      +
    • +
      +
      + {{ form.email }} +
      +
      +
      + +
    • +
    • +
      +
      -
      -
      -
      +
    +
    +
  • -
    -
    - {{ form.city }} -
    -
    -
    +
    +
    + {{ form.city }} +
    +
    +
  • - - - +
    {% trans 'Номер телефона' %}
    + + - + diff --git a/theme/admin.py b/theme/admin.py index 593e18f8..da323984 100644 --- a/theme/admin.py +++ b/theme/admin.py @@ -147,20 +147,17 @@ def search_tag(request): else: qs = Tag.objects.filter(theme__id__in=theme_ids, translations__name__contains=term) - tags = [{'id': tag.id, 'label': '%s(%s)'%(tag.name, tag.theme.name)} for tag in qs] + return HttpResponse(json.dumps(tags), content_type='application/json') - """ - tags = [] - for id in theme_ids: - if not term: - t = Tag.objects.filter(theme__id=id) - else: - t = Tag.objects.filter(theme__id=id, translations__name__contains=term) - cur_theme_tag = [{'id': tag.id, 'label': '%s(%s)'%(tag.name, tag.theme.name)} for tag in t] - tags = tags +cur_theme_tag - """ +def search2(request): + term = request.GET['term'] + if not term: + qs = Tag.objects.filter().order_by('translations__name')[:50] + else: + qs = Tag.objects.filter(translations__name__contains=term)[:50] + tags = [{'id': tag.id, 'text': '%s(%s)'%(tag.name, tag.theme.name)} for tag in qs] return HttpResponse(json.dumps(tags), content_type='application/json') diff --git a/theme/admin_urls.py b/theme/admin_urls.py index a2b34061..c1803d4f 100644 --- a/theme/admin_urls.py +++ b/theme/admin_urls.py @@ -16,4 +16,5 @@ urlpatterns = patterns('theme.admin', url(r'^theme/all/$', ThemeListView.as_view()), url(r'^tag/all/$', TagListView.as_view()), url(r'^tag/search/$', 'search_tag'), + url(r'^tag/search-without-theme/$', 'search2'), ) diff --git a/wizard/views.py b/wizard/views.py index 0f18246d..34203aa4 100644 --- a/wizard/views.py +++ b/wizard/views.py @@ -8,6 +8,7 @@ from exposition.models import Exposition, Statistic from functions.form_check import translit_with_separator from django.http import HttpResponseRedirect + # defining different template for every form TEMPLATES = {'0':'client/wizard/first_step.html', '1':'client/wizard/second_step.html'}
    {% trans 'Номер телефона' %} -
    -
    - {{ form.code_country }} -

    {{ form.code_country.label }}

    -
    -
    -
    +
    +
    + {{ form.code_country }} +

    {{ form.code_country.label }}

    + +
    +
    +
    -
    -
    - {{ form.code_city }} -

    {{ form.code_city.label }}

    -
    -
    +
    +
    + {{ form.code_city }} +

    {{ form.code_city.label }}

    +
    +
    -
    +
    -
    -
    - {{ form.phone }} -

    {{ form.phone.label }}

    -
    -
    -
    +
    +
    + {{ form.phone }} +

    {{ form.phone.label }}

    +
    +
    +
    www.expomap.ru/www.expomap.ru/ -
    -
    - {{ form.url }} -
    -
    ivanova
    -
    -
    +
    +
    + {{ form.url }} +
    +
    ivanova
    +
    +