diff --git a/accounts/search_indexes.py b/accounts/search_indexes.py index 394b9993..0b9b391d 100644 --- a/accounts/search_indexes.py +++ b/accounts/search_indexes.py @@ -1,11 +1,11 @@ from haystack import indexes from models import User -""" +""" class UserIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) - first_name = indexes.CharField(model_attr='first_name') - last_name = indexes.CharField(model_attr='last_name') +# first_name = indexes.CharField(model_attr='first_name') +# last_name = indexes.CharField(model_attr='last_name') email = indexes.NgramField(model_attr='email') #email = indexes.CharField(model_attr='email') diff --git a/article/admin.py b/article/admin.py index 26801086..18722821 100644 --- a/article/admin.py +++ b/article/admin.py @@ -147,9 +147,6 @@ class BlogView(FormView): form.save(author, article=self.obj) return HttpResponseRedirect(self.success_url) - def form_invalid(self, form): - - return HttpResponse(form.errors) def get_form(self, form_class): if self.request.POST: diff --git a/company/search_indexes.py b/company/search_indexes.py index 2d5cfc4c..effe4c55 100644 --- a/company/search_indexes.py +++ b/company/search_indexes.py @@ -1,6 +1,6 @@ from haystack import indexes from models import Company - +""" class CompanyIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) where = indexes.MultiValueField() @@ -15,8 +15,8 @@ class CompanyIndex(indexes.SearchIndex, indexes.Indexable): return '' def prepare_city(self, obj): - if obj.country: - return '%s'%obj.country.city + if obj.city: + return '%s'%obj.city.id return '' def prepare_theme(self, obj): @@ -43,3 +43,4 @@ class CompanyIndex(indexes.SearchIndex, indexes.Indexable): return self.get_model().objects.filter() +""" \ No newline at end of file diff --git a/exposition/search_indexes.py b/exposition/search_indexes.py index af583d49..670f82bd 100644 --- a/exposition/search_indexes.py +++ b/exposition/search_indexes.py @@ -39,5 +39,4 @@ class ExpositionIndex(indexes.SearchIndex, indexes.Indexable): def index_queryset(self, using=None): - return self.get_model().objects.filter(is_published=True) - + return self.get_model().objects.filter(is_published=True) \ No newline at end of file diff --git a/functions/search_forms.py b/functions/search_forms.py index 132467ce..ce554950 100644 --- a/functions/search_forms.py +++ b/functions/search_forms.py @@ -18,6 +18,9 @@ class AbstactSearchForm(forms.Form): q = forms.CharField(label=_(u'Поиск'), required=False) w = forms.CharField(label=_(u'Где'), required=False) + + + class CompanySearchForm(AbstactSearchForm): th = forms.MultipleChoiceField(label=_(u'Тематика'), required=False, choices=[(theme.id, theme.name) for theme in Theme.objects.all()]) @@ -78,8 +81,10 @@ class CompanySearchForm(AbstactSearchForm): from country.models import Area from theme.models import Theme +from django.utils import translation class ExpositionSearchForm(forms.Form): + search_url = '/expo/search/' q = forms.CharField(label=_(u'Поиск'), required=False) w = forms.CharField(label=_(u'Где'), required=False) @@ -89,7 +94,11 @@ class ExpositionSearchForm(forms.Form): area = forms.MultipleChoiceField(label=_(u'Регион'), choices=[(item.id, item.name) for item in Area.objects.language()], required=False, widget=forms.CheckboxSelectMultiple()) - co = forms.CharField(label=_(u'Страна'), required=False, widget=forms.SelectMultiple()) + co = forms.MultipleChoiceField(label=_(u'Страна'), choices=[(item.id, item.name) for item in Country.objects.select_related('exposition_country')\ + .filter(exposition_country__country__isnull=False, translations__language_code=translation.get_language())\ + .order_by('translations__name').distinct()], + required=False, widget=forms.CheckboxSelectMultiple()) + #co = forms.CharField(label=_(u'Страна'), required=False, widget=forms.SelectMultiple()) ci = forms.CharField(label=_(u'Город'), required=False, widget=forms.SelectMultiple()) fr = forms.DateField(required=False, @@ -99,6 +108,25 @@ class ExpositionSearchForm(forms.Form): widget=forms.DateInput(attrs={'class': 'date', 'id': 'dateTo', 'placeholder': _(u'дд.мм.гггг')})) + def get_places_display(self): + display = '' + self.is_valid() + area = self.cleaned_data['area'] + area_choices = self.fields['area'].choices + + places = [choice[1] for choice in area_choices if str(choice[0]) in area] + + country = self.cleaned_data['co'] + country_choices = self.fields['co'].choices + places += [choice[1] for choice in country_choices if str(choice[0]) in country] + + + if not places: + return _(u'Не важно') + return ', '.join(places) + + + """ def clean_area(self): @@ -107,7 +135,7 @@ class ExpositionSearchForm(forms.Form): res = ast.literal_eval(area) return res return area - """ + def clean_co(self): @@ -117,6 +145,8 @@ class ExpositionSearchForm(forms.Form): return res return co + """ + def clean_ci(self): ci = self.cleaned_data.get('ci') diff --git a/photologue/admin.py b/photologue/admin.py index cd3101e7..331da3e7 100644 --- a/photologue/admin.py +++ b/photologue/admin.py @@ -1,3 +1,4 @@ + from django import forms from django.conf import settings from django.contrib import admin @@ -12,7 +13,7 @@ MULTISITE = getattr(settings, 'PHOTOLOGUE_MULTISITE', False) ENABLE_TAGS = getattr(settings, 'PHOTOLOGUE_ENABLE_TAGS', False) - +""" class GalleryAdminForm(forms.ModelForm): class Meta: @@ -44,16 +45,16 @@ class GalleryAdmin(admin.ModelAdmin): ] def formfield_for_manytomany(self, db_field, request, **kwargs): - """ Set the current site as initial value. """ + ''' Set the current site as initial value. ''' if db_field.name == "sites": kwargs["initial"] = [Site.objects.get_current()] return super(GalleryAdmin, self).formfield_for_manytomany(db_field, request, **kwargs) def save_related(self, request, form, *args, **kwargs): - """ + ''' If the user has saved a gallery with a photo that belongs only to different Sites - it might cause much confusion. So let them know. - """ + ''' super(GalleryAdmin, self).save_related(request, form, *args, **kwargs) orphaned_photos = form.instance.orphaned_photos() if orphaned_photos: @@ -172,7 +173,7 @@ class PhotoAdmin(admin.ModelAdmin): actions = ['add_photos_to_current_site', 'remove_photos_from_current_site'] def formfield_for_manytomany(self, db_field, request, **kwargs): - """ Set the current site as initial value. """ + ''' Set the current site as initial value. ''' if db_field.name == "sites": kwargs["initial"] = [Site.objects.get_current()] return super(PhotoAdmin, self).formfield_for_manytomany(db_field, request, **kwargs) @@ -252,3 +253,108 @@ class WatermarkAdmin(admin.ModelAdmin): admin.site.register(Watermark, WatermarkAdmin) +""" + +#------------------EXPOMAP VIEWS---------------------------------------------- +from django.views.generic import ListView, FormView +from forms import PhotoForm, GalleryForm +from django.shortcuts import render_to_response, get_object_or_404 +from django.http import HttpResponseRedirect + +class AdminViewObject(FormView): + """ + need overwrite get_form method for every class + """ + form_class = None + model = None + template_name = None + success_url = None + obj = None + + def set_obj(self): + """ + this method must be called in get_form method + to determine if we changing or creating + + """ + slug = self.kwargs.get('slug') + if slug: + obj = get_object_or_404(self.model, slug=slug) + self.obj =obj + else: + self.obj = None + + def form_valid(self, form): + form.save(obj=self.obj) + return HttpResponseRedirect(self.success_url) + + def get_context_data(self, **kwargs): + context = super(AdminViewObject, self).get_context_data(**kwargs) + context['object'] = self.obj + context['languages'] = settings.LANGUAGES + return context + + + +class PhotoView(AdminViewObject): + model = Photo + form_class = PhotoForm + template_name = 'photogallery/admin_photo.html' + success_url = '/admin/photogallery/photo/all/' + + def get_form(self, form_class): + + if self.request.POST: + return super(PhotoView, self).get_form(form_class) + + self.set_obj() + + if self.obj: + photo = self.obj + data = {} + data['image'] = photo.image.url + + for code, name in settings.LANGUAGES: + obj = Photo._meta.translations_model.objects.get(language_code = code,master__id=getattr(photo, 'id')) #access to translated fields + data['title_%s' % code] = obj.title + data['caption_%s' % code] = obj.caption + #form.fields['tag'].widget.attrs['data-init-text'] = [item.name for item in article.tag.all()] + return form_class(data) + else: + return form_class() + +class GalleryView(AdminViewObject): + model = Gallery + form_class = GalleryForm + template_name = 'photogallery/admin_gallery.html' + success_url = '/admin/photogallery/gallery/all/' + + def get_form(self, form_class): + + if self.request.POST: + return super(GalleryView, self).get_form(form_class) + + self.set_obj() + + if self.obj: + gallery = self.obj + data = {} + + for code, name in settings.LANGUAGES: + obj = Gallery._meta.translations_model.objects.get(language_code = code,master__id=getattr(gallery, 'id')) #access to translated fields + data['title_%s' % code] = obj.title + data['description_%s' % code] = obj.description + #form.fields['tag'].widget.attrs['data-init-text'] = [item.name for item in article.tag.all()] + return form_class(data) + else: + return form_class() + + +class PhotoListView(ListView): + model = Photo + template_name = 'photogallery/admin_photo_list.html' + + +class GalleryListView(ListView): + model = Gallery + template_name = 'photogallery/admin_gallery_list.html' \ No newline at end of file diff --git a/photologue/admin_urls.py b/photologue/admin_urls.py new file mode 100644 index 00000000..6981f659 --- /dev/null +++ b/photologue/admin_urls.py @@ -0,0 +1,14 @@ +# -*- coding: utf-8 -*- +from django.conf.urls import patterns, url +from admin import GalleryView, PhotoView, PhotoListView, GalleryListView + +urlpatterns = patterns('', + url(r'^gallery/all/$', GalleryListView.as_view()), + url(r'^photo/all/$', PhotoListView.as_view()), + + url(r'^gallery/$', GalleryView.as_view()), + url(r'^photo/$', PhotoView.as_view()), + + url(r'^photo/(?P.*)/$', PhotoView.as_view()), + url(r'^gallery/(?P.*)/$', GalleryView.as_view()), +) diff --git a/photologue/client_urls.py b/photologue/client_urls.py new file mode 100644 index 00000000..9459fe8e --- /dev/null +++ b/photologue/client_urls.py @@ -0,0 +1,9 @@ +# -*- coding: utf-8 -*- +from django.conf.urls import patterns, url +from client_view import GalleryView, PhotoView + +urlpatterns = patterns('', + url(r'gallery/(?P.*)$', GalleryView.as_view()), + url(r'photo/(?P.*)$', PhotoView.as_view()), +) + diff --git a/photologue/client_view.py b/photologue/client_view.py new file mode 100644 index 00000000..cced3417 --- /dev/null +++ b/photologue/client_view.py @@ -0,0 +1,31 @@ +import warnings +from django.conf import settings +from django.views.generic import DetailView, ListView +from photologue.models import Gallery, Photo + + +# Number of galleries to display per page. +GALLERY_PAGINATE_BY = getattr(settings, 'PHOTOLOGUE_GALLERY_PAGINATE_BY', 20) + +if GALLERY_PAGINATE_BY != 20: + warnings.warn( + DeprecationWarning('PHOTOLOGUE_GALLERY_PAGINATE_BY setting will be removed in Photologue 3.1')) + +# Number of photos to display per page. +PHOTO_PAGINATE_BY = getattr(settings, 'PHOTOLOGUE_PHOTO_PAGINATE_BY', 20) + +if PHOTO_PAGINATE_BY != 20: + warnings.warn( + DeprecationWarning('PHOTOLOGUE_PHOTO_PAGINATE_BY setting will be removed in Photologue 3.1')) + +class GalleryView(DetailView): + model = Gallery + slug_field = 'slug' + template_name = 'client/photoreport/gallery.html' + + +class PhotoView(DetailView): + model = Photo + slug_field = 'slug' + template_name = 'client/photoreport/photo.html' + diff --git a/photologue/forms.py b/photologue/forms.py new file mode 100644 index 00000000..18decbcf --- /dev/null +++ b/photologue/forms.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +from django import forms +from django.conf import settings +from functions.translate import fill_with_signal +from models import Gallery, Photo + + +class GalleryForm(forms.Form): + def __init__(self, *args, **kwargs): + """ + create dynamical translated fields fields + """ + super(GalleryForm, 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['title_%s' % code] = forms.CharField(label='Описание', required=required) + self.fields['description_%s' % code] = forms.CharField(label='Заголовок', required=required) + + def save(self, obj=None): + data = self.cleaned_data + #create new Gallery object or get exists + if not obj: + gallery = Gallery() + else: + gallery = obj + + fill_with_signal(Gallery, gallery, data) + return gallery + + + + +class PhotoForm(forms.Form): + image = forms.ImageField(label=u'Изображение') + + + def __init__(self, *args, **kwargs): + """ + create dynamical translated fields fields + """ + super(PhotoForm, 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['title_%s' % code] = forms.CharField(label='Описание', required=required) + self.fields['caption_%s' % code] = forms.CharField(label='Заголовок', required=required) + + def save(self, obj=None): + data = self.cleaned_data + #create new Photo object or get exists + if not obj: + photo = Photo() + else: + photo = obj + + photo.image = data['image'] + fill_with_signal(Photo, photo, data) + return photo + + +class GalleryPhotoForm(PhotoForm): + def save(self, obj=None, gallery=None): + photo = super(GalleryPhotoForm, self).save(obj) + gallery.add(photo) \ No newline at end of file diff --git a/photologue/managers.py b/photologue/managers.py index 61a440e6..4c637fe9 100644 --- a/photologue/managers.py +++ b/photologue/managers.py @@ -1,5 +1,6 @@ from django.db.models.query import QuerySet from django.conf import settings +from hvad.models import TranslationManager class SharedQueries(object): @@ -15,9 +16,18 @@ class SharedQueries(object): return self.filter(sites__id=settings.SITE_ID) -class GalleryQuerySet(SharedQueries, QuerySet): +class GalleryQuerySet(SharedQueries, TranslationManager): pass class PhotoQuerySet(SharedQueries, QuerySet): pass + +class PhotologueManager(TranslationManager): + def is_public(self): + """Trivial filter - will probably become more complex as time goes by!""" + return self.filter(is_public=True) + + def on_site(self): + """Return objects linked to the current site only.""" + return self.filter(sites__id=settings.SITE_ID) \ No newline at end of file diff --git a/photologue/models.py b/photologue/models.py index 2ee0cce4..52e8cb7e 100644 --- a/photologue/models.py +++ b/photologue/models.py @@ -49,6 +49,7 @@ except ImportError: from sortedm2m.fields import SortedManyToManyField from model_utils.managers import PassThroughManager +from hvad.models import TranslatableModel, TranslatedFields, TranslationManager # attempt to load the django-tagging TagField from default location, # otherwise we substitude a dummy TagField. @@ -75,7 +76,9 @@ except ImportError: from .utils import EXIF from .utils.reflection import add_reflection from .utils.watermark import apply_watermark -from .managers import GalleryQuerySet, PhotoQuerySet +from .managers import GalleryQuerySet, PhotoQuerySet, PhotologueManager +from functions.url_utils import slugify, unique_slug +from functions.model_utils import base_concrete_model logger = logging.getLogger('photologue.models') @@ -157,17 +160,18 @@ IMAGE_FILTERS_HELP_TEXT = _( @python_2_unicode_compatible -class Gallery(models.Model): +class Gallery(TranslatableModel): + translations = TranslatedFields( + title = models.CharField(_('title'), max_length=50), + description = models.TextField(_('description'), blank=True) + ) date_added = models.DateTimeField(_('date published'), default=now) - title = models.CharField(_('title'), - max_length=50, - unique=True) + slug = models.SlugField(_('title slug'), unique=True, help_text=_('A "slug" is a unique URL-friendly title for an object.')) - description = models.TextField(_('description'), - blank=True) + is_public = models.BooleanField(_('is public'), default=True, help_text=_('Public galleries will be displayed ' @@ -181,7 +185,7 @@ class Gallery(models.Model): sites = models.ManyToManyField(Site, verbose_name=_(u'sites'), blank=True, null=True) - objects = PassThroughManager.for_queryset_class(GalleryQuerySet)() + objects = PhotologueManager() class Meta: ordering = ['-date_added'] @@ -190,7 +194,39 @@ class Gallery(models.Model): verbose_name_plural = _('galleries') def __str__(self): - return self.title + return self.lazy_translation_getter('title', self.pk) + + def admin_url(self): + return '/admin/photogallery/gallery/%s'%self.slug + + def translation_model(self): + return self._meta.translations_model + + def generate_unique_slug(self): + """ + Create a unique slug by passing the result of get_slug() to + utils.urls.unique_slug, which appends an index if necessary. + """ + # For custom content types, use the ``Page`` instance for + # slug lookup. + concrete_model = base_concrete_model(Photo, self) + slug_qs = concrete_model.objects.exclude(id=self.id) + return unique_slug(slug_qs, "slug", self.get_slug()) + + def get_slug(self): + """ + Allows subclasses to implement their own slug creation logic. + """ + return slugify(self.get_available_title()) + + def get_available_title(self): + #print self.lazy_translation_getter('main_title', self.pk) + return u'%s'%self.lazy_translation_getter('title', self.pk) + + def save(self, *args, **kwargs): + if not self.slug: + self.slug = self.generate_unique_slug() + super(Gallery, self).save(*args, **kwargs) def get_absolute_url(self): return reverse('pl-gallery', args=[self.slug]) @@ -642,15 +678,18 @@ class ImageModel(models.Model): @python_2_unicode_compatible -class Photo(ImageModel): - title = models.CharField(_('title'), - max_length=50, - unique=True) +class Photo(TranslatableModel, ImageModel): + translations = TranslatedFields( + title = models.CharField(_('title'), + max_length=50), + caption = models.TextField(_('caption'), + blank=True) + ) + slug = models.SlugField(_('slug'), unique=True, help_text=_('A "slug" is a unique URL-friendly title for an object.')) - caption = models.TextField(_('caption'), - blank=True) + date_added = models.DateTimeField(_('date added'), default=now) is_public = models.BooleanField(_('is public'), @@ -660,7 +699,7 @@ class Photo(ImageModel): sites = models.ManyToManyField(Site, verbose_name=_(u'sites'), blank=True, null=True) - objects = PassThroughManager.for_queryset_class(PhotoQuerySet)() + objects = PhotologueManager() class Meta: ordering = ['-date_added'] @@ -669,11 +708,38 @@ class Photo(ImageModel): verbose_name_plural = _("photos") def __str__(self): - return self.title + return self.get_available_title() + + def translation_model(self): + return self._meta.translations_model + + def admin_url(self): + return '/admin/photogallery/photo/%s'%self.slug + + def generate_unique_slug(self): + """ + Create a unique slug by passing the result of get_slug() to + utils.urls.unique_slug, which appends an index if necessary. + """ + # For custom content types, use the ``Page`` instance for + # slug lookup. + concrete_model = base_concrete_model(Photo, self) + slug_qs = concrete_model.objects.exclude(id=self.id) + return unique_slug(slug_qs, "slug", self.get_slug()) + + def get_slug(self): + """ + Allows subclasses to implement their own slug creation logic. + """ + return slugify(self.get_available_title()) + + def get_available_title(self): + #print self.lazy_translation_getter('main_title', self.pk) + return u'%s'%self.lazy_translation_getter('title', self.pk) def save(self, *args, **kwargs): - if self.slug is None: - self.slug = slugify(self.title) + if not self.slug: + self.slug = self.generate_unique_slug() super(Photo, self).save(*args, **kwargs) def get_absolute_url(self): @@ -1018,3 +1084,10 @@ def add_default_site(instance, created, **kwargs): instance.sites.add(Site.objects.get_current()) post_save.connect(add_default_site, sender=Gallery) post_save.connect(add_default_site, sender=Photo) + + +from django.db.models.signals import post_save +from functions.signal_handlers import post_save_handler + +post_save.connect(post_save_handler, sender=Photo) +post_save.connect(post_save_handler, sender=Gallery) \ No newline at end of file diff --git a/photologue/templates/photologue/gallery_detail.html b/photologue/templates/photologue/gallery_detail.html index eea213de..7aaf160d 100644 --- a/photologue/templates/photologue/gallery_detail.html +++ b/photologue/templates/photologue/gallery_detail.html @@ -13,7 +13,7 @@ {% for photo in gallery.public %} - {{ photo.title }} + {{ photo.title }} {% endfor %} diff --git a/place_exposition/search_indexes.py b/place_exposition/search_indexes.py index b71900c8..6dc54a7e 100644 --- a/place_exposition/search_indexes.py +++ b/place_exposition/search_indexes.py @@ -5,9 +5,9 @@ from models import PlaceExposition class PlaceExpositionIndex(indexes.SearchIndex, indexes.Indexable): text = indexes.CharField(document=True, use_template=True) where = indexes.MultiValueField() - #country = indexes.CharField(model_attr='country', null=True) + country = indexes.CharField(model_attr='country', null=True) #city = indexes.CharField(model_attr='city', null=True) - """ + def prepare_country(self, obj): if obj.country: return '%s'%obj.country.id @@ -17,7 +17,6 @@ class PlaceExpositionIndex(indexes.SearchIndex, indexes.Indexable): if obj.city: return '%s'%obj.country.city return '' - """ def prepare_where(self, obj): country = [tr.name for tr in obj.country.translations.all()] diff --git a/proj/admin_urls.py b/proj/admin_urls.py index 997f0d76..f499cc8c 100644 --- a/proj/admin_urls.py +++ b/proj/admin_urls.py @@ -12,6 +12,7 @@ urlpatterns = required( url(r'^', include('import_xls.admin_urls')), url(r'^accounts/', include('accounts.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')), diff --git a/proj/settings.py b/proj/settings.py index 261923a3..85faf41c 100644 --- a/proj/settings.py +++ b/proj/settings.py @@ -327,6 +327,8 @@ INSTALLED_APPS = ( 'webinar', #django modules 'sorl.thumbnail', + 'photologue', + 'sortedm2m', 'hvad', 'tinymce', 'ckeditor', @@ -337,7 +339,7 @@ INSTALLED_APPS = ( 'password_reset', #'social_auth', 'social.apps.django_app.default', - #'south', + 'south', #'debug_toolbar', ) @@ -345,7 +347,7 @@ INSTALLED_APPS = ( HAYSTACK_CONNECTIONS = { 'default': { 'ENGINE': 'haystack.backends.solr_backend.SolrEngine', - 'URL': 'http://127.0.0.1:8983/solr' + 'URL': 'http://localhost:8983/solr' # ...or for multicore... # 'URL': 'http://127.0.0.1:8983/solr/mysite', }, diff --git a/proj/urls.py b/proj/urls.py index 53b8125c..2f97aa4b 100644 --- a/proj/urls.py +++ b/proj/urls.py @@ -5,8 +5,12 @@ from core.views import PlaceListView, PlacePhotoView, PlaceSearchView, EventSear from core.simple_index_view import AdvertisingView, AboutView from views import MainPageView +from django.http import HttpResponse +def robots(request): + return HttpResponse('User-agent: * \nDisallow: /', content_type='text/plain') urlpatterns = patterns('', + url(r'^robots.txt$', robots), url(r'^$', MainPageView.as_view()), url(r'^theme/', include('theme.urls')), url(r'^', include('accounts.urls')), @@ -20,6 +24,7 @@ urlpatterns = patterns('', url(r'^country/', include('country.urls')), url(r'^city/', include('city.urls')), url(r'^organiser/', include('organiser.urls')), + url(r'^gallery/', include('photologue.client_urls')), url(r'^', include('file.urls')), @@ -71,4 +76,4 @@ if settings.DEBUG: import debug_toolbar urlpatterns += patterns('', url(r'^__debug__/', include(debug_toolbar.urls)), - ) \ No newline at end of file + ) diff --git a/schema.xml b/schema.xml index 6af8aead..e27a2dfd 100644 --- a/schema.xml +++ b/schema.xml @@ -1,21 +1,3 @@ - - - @@ -26,19 +8,29 @@ a string value that isn't human-readable in its internal form, but with a lexicographic ordering the same as the numeric ordering, so that range queries work correctly. --> - - - - - - - - - - - + + + + + + + + + + + - + @@ -47,15 +39,18 @@ - + - + @@ -117,13 +112,15 @@ - + - + @@ -148,9 +145,17 @@ - + + + + + + + + + - + diff --git a/scheme.xml b/scheme.xml new file mode 100644 index 00000000..740bd3ae --- /dev/null +++ b/scheme.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id + + + text + + + + + diff --git a/static/client/js/main.js b/static/client/js/main.js index bda63b9b..013a924f 100644 --- a/static/client/js/main.js +++ b/static/client/js/main.js @@ -97,6 +97,9 @@ function placeInput(width){ /* submiting registration form */ $(function () { + + //-------------------------------------------- + $('.pw-place form').submit(function() { $(this).find('.places-list li.level2 label span input:checked').each(function() { $(this).parents().eq(2).find('ul li input:checked').each(function() { @@ -110,7 +113,8 @@ function placeInput(width){ }); }); return false; - }); + }); + $('.search_form').on('submit', function(e){ e.preventDefault(); var action = $(this).attr('action'); @@ -2023,7 +2027,7 @@ function placeInput(width){ $reply.find('#id_recipient').val(sender) $reply.find('#reply_message').val(reply_message) }); - //-------------------------------------------- + }); diff --git a/static/client/js/pages/profile.js b/static/client/js/pages/profile.js index 735bdf73..a59e3747 100644 --- a/static/client/js/pages/profile.js +++ b/static/client/js/pages/profile.js @@ -1,14 +1,19 @@ function handleNameForm(data){ if (data.success){ + /* var fname = $this.find('#id_first_name').val() var lname = $this.find('#id_last_name').val() $this.parent().parent().prev().html(fname+' '+lname) $this.next().click() + */ + window.location.reload(); } } function handleHomeForm(data){ if (data.success){ + window.location.reload(); + /* var country = $this.find('#id_country option:selected').text(); var city = $this.find('#id_city option:selected').text(); @@ -17,11 +22,14 @@ function handleHomeForm(data){ $this.parent().parent().prev().prev().find('a').html(country); $this.next().click() + */ } } function handleWorkForm(data){ if (data.success){ + window.location.reload(); + /* var position = $this.find('#id_position').val(); var work = $this.find('#id_work').val(); @@ -33,19 +41,25 @@ function handleWorkForm(data){ $this.parent().parent().prev().html(result); $this.next().click() + */ } } function handleAboutCompanyForm(data){ if (data.success){ + window.location.reload(); + /* var about_company = $this.find('#id_about_company').val(); $this.parent().parent().prev().html(about_company); $this.next().click(); + */ } } function handleSocialForm(data){ if (data.success){ + window.location.reload(); + /* var fb = $this.find('#id_facebook').val(); var li = $this.find('#id_linkedin').val(); var tw = $this.find('#id_twitter').val(); @@ -63,41 +77,54 @@ function handleSocialForm(data){ $ul.find('li:eq(3) a').attr('href', tw); $this.next().click(); + */ } } function handlePhoneForm(data){ if (data.success){ + window.location.reload(); + /* var phone = $this.find('#id_phone').val() phone = '+'+phone.replace(/(\d{2})(\d{3})(\d{3})(\d{4})/, "$1 $2 $3 $4"); $this.parent().parent().prev().html(phone) $this.next().click() + */ } } function handleEmailForm(data){ if (data.success){ + window.location.reload(); + /* var email = $this.find('#id_email').val() $this.parent().parent().prev().html(email) $this.parent().parent().prev().attr('href', 'mailto:'+url) $this.next().click() + */ } } function handleWebPageForm(data){ - if (data.success){ + if (data.success){ + window.location.reload(); + /* var url = $this.find('#id_web_page').val() $this.parent().parent().prev().attr('href', url) $this.parent().parent().prev().html(url) $this.next().click() + */ } } function handleAboutForm(data){ if (data.success){ + window.location.reload(); + /* var about = $this.find('#id_about').val() $this.parent().parent().prev().html(about) $this.next().click() + */ } } @@ -105,7 +132,6 @@ function handleCreateCompany(data){ if(data.success){ window.location = '/profile/company/' } - console.log(data); } function formHandler(id, handleFunction){ diff --git a/static/client/js/sendfilter.js b/static/client/js/sendfilter.js new file mode 100644 index 00000000..2bcd81c9 --- /dev/null +++ b/static/client/js/sendfilter.js @@ -0,0 +1,16 @@ +jQuery(function(){ + $('.pw-place form').submit(function() { + $(this).find('.places-list li.level2 label span input:checked').each(function() { + $(this).parents().eq(2).find('ul li input:checked').each(function() { + $(this).prop('checked', false); + } + ); + }); + $(this).find('.places-list li.level1 label span input:checked').each(function() { + $(this).parents().eq(3).find('ul input:checked').each(function() { + $(this).prop('checked', false); + }); + }); + return false; + }); +}); \ No newline at end of file diff --git a/templates/admin/photogallery/admin_gallery.html b/templates/admin/photogallery/admin_gallery.html new file mode 100644 index 00000000..4230176b --- /dev/null +++ b/templates/admin/photogallery/admin_gallery.html @@ -0,0 +1,58 @@ +{% extends 'base.html' %} +{% load static %} +{# Displays article form #} + + {% block scripts %} + + + {# selects #} + + + + {# ajax #} + + + + {% endblock %} + +{% block body %} +
{% csrf_token %} +
+ {% if object %} Изменить {% else %} Добавить {% endif %}статью + +
+
+

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

+
+
+ {# description #} + {% include 'admin/forms/multilang.html' with field='description' form=form languages=languages %} + {# title #} + {% include 'admin/forms/multilang.html' with field='title' form=form languages=languages %} + +
+
+
+
+

Фотографии

+
+
+ Добавить фото +
+ {# image #} + {% for photo in object.photos.all %} +
+ {{ photo.title }} +
+ {% endfor %} +
+
+
+ + + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/admin/photogallery/admin_gallery_list.html b/templates/admin/photogallery/admin_gallery_list.html new file mode 100644 index 00000000..c8defc5f --- /dev/null +++ b/templates/admin/photogallery/admin_gallery_list.html @@ -0,0 +1,47 @@ +{% extends 'base.html' %} +{% block body %} +
+
+

Список галерей

+
+
+ + + + + + + + + + {% for item in object_list %} + + + + + + + + + + {% endfor %} + +
Заголовок 
{{ item.title }} + + Изменить + + + + Копировать + + + + Удалить + +
+ + Добавить фото + +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/admin/photogallery/admin_photo.html b/templates/admin/photogallery/admin_photo.html new file mode 100644 index 00000000..685c4ea6 --- /dev/null +++ b/templates/admin/photogallery/admin_photo.html @@ -0,0 +1,52 @@ +{% extends 'base.html' %} +{% load static %} +{% load photologue_tags i18n %} + + + {% block scripts %} + + + {# selects #} + + + + {# ajax #} + + + + {% endblock %} + +{% block body %} +
{% csrf_token %} +
+ {% if object %} Изменить {% else %} Добавить {% endif %}фото + +
+
+

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

+
+
+ {# image #} +
+ +
+ {{ form.image }} + {{ form.image.errors }} +
+
+ {{ object.title }} + {# title #} + {% include 'admin/forms/multilang.html' with field='title' form=form languages=languages %} + {# caption #} + {% include 'admin/forms/multilang.html' with field='caption' form=form languages=languages %} +
+
+
+ + + +
+
+
+ +{% endblock %} \ No newline at end of file diff --git a/templates/admin/photogallery/admin_photo_list.html b/templates/admin/photogallery/admin_photo_list.html new file mode 100644 index 00000000..4ed25a42 --- /dev/null +++ b/templates/admin/photogallery/admin_photo_list.html @@ -0,0 +1,51 @@ +{% extends 'base.html' %} +{% block body %} +
+
+

Список фотографий

+
+
+ + + + + + + + + + + {% for item in object_list %} + + + + + + + + + + + {% endfor %} + +
Заголовок  
{{ item.title }} + {{ item.title }} + + + Изменить + + + + Копировать + + + + Удалить + +
+ + Добавить фото + +
+
+{% endblock %} \ No newline at end of file diff --git a/templates/client/includes/catalog_search.html b/templates/client/includes/catalog_search.html index 6039c73a..10cc9dee 100644 --- a/templates/client/includes/catalog_search.html +++ b/templates/client/includes/catalog_search.html @@ -2,7 +2,7 @@ {% load i18n %}
-
+
{% if type %}{{ type }}{% else %}{% trans 'поиск событий' %}{% endif %}
@@ -24,8 +24,28 @@
{% ifnotequal type 'places search' %}
{% trans 'Тематика: ' %}Не важно
{% endifnotequal %} -
{% trans 'Место: ' %}Не важно
- {% ifnotequal type 'places search' %}
{% trans 'Период: ' %}Не важно
{% endifnotequal %} + +
{% trans 'Место: ' %} + + {{ search_form.get_places_display }} +
+ + {% ifnotequal type 'places search' %} + + {% endifnotequal %}
diff --git a/templates/client/photoreport/gallery.html b/templates/client/photoreport/gallery.html new file mode 100644 index 00000000..b386e7b1 --- /dev/null +++ b/templates/client/photoreport/gallery.html @@ -0,0 +1,126 @@ +{% extends 'base_catalog.html' %} + +{% load i18n %} +{% load static %} + + +{% block page_body %} +
+
+
+ +
+
+
+ +
+
+ {{ photoreport.get_event.main_title|safe }} +
+
+
+
+ {% with obj=photoreport.get_event %} + {% include 'client/includes/show_date_block.html' %} + {% endwith %} +
+ + + +
+
+
+
+
+ {{ photoreport.description|safe }} +
+ +
+{% endblock %} + +{% block photogallery %} + +{% endblock %} \ No newline at end of file diff --git a/templates/client/photoreport/photo.html b/templates/client/photoreport/photo.html new file mode 100644 index 00000000..625ff63c --- /dev/null +++ b/templates/client/photoreport/photo.html @@ -0,0 +1,10 @@ +{% extends 'base_catalog.html' %} + +{% load i18n %} +{% load static %} + + +{% block page_body %} + + {% include 'client/popups/photo.html' with photo=object %} +{% endblock %} \ No newline at end of file diff --git a/templates/client/popups/photo.html b/templates/client/popups/photo.html new file mode 100644 index 00000000..2cbfbc7f --- /dev/null +++ b/templates/client/popups/photo.html @@ -0,0 +1,61 @@ +{% load i18n %} +{% load static %} + + + diff --git a/templates/client/popups/place.html b/templates/client/popups/place.html index b37cd534..c7ae4add 100644 --- a/templates/client/popups/place.html +++ b/templates/client/popups/place.html @@ -7,7 +7,7 @@
{% trans 'Место' %}
-
+
@@ -31,7 +31,7 @@
    {% for country in value|get_country_by_area %}
  • - + {{ country.name }} {% if country.id|get_city_by_country %}
      @@ -48,7 +48,7 @@ {% endif %} {% endfor %} - {{ search_form.area }} +