diff --git a/events/forms.py b/events/forms.py index 013d46e9..51e4d0cd 100644 --- a/events/forms.py +++ b/events/forms.py @@ -3,11 +3,11 @@ from itertools import chain from django import forms -from django.utils.translation import ugettext as _ +from django.utils.translation import get_language, ugettext as _ from django.utils.encoding import smart_text, force_text from django.utils.html import format_html from django.utils.safestring import mark_safe -from django.db.models import Count, Sum +from django.db.models import Count, Sum, Q from haystack.query import SearchQuerySet, RelatedSearchQuerySet @@ -19,7 +19,7 @@ from theme.models import Theme, Tag class CountModelMultipleChoiceField(forms.ModelMultipleChoiceField): def label_from_instance(self, obj): - return u'{0} ({count})'.format(smart_text(obj.name), count=obj.e_count + obj.c_count) + return u'{label} ({count})'.format(label=smart_text(obj.name), count=obj.count) @@ -69,27 +69,11 @@ class CountModelMultipleChoiceField(forms.ModelMultipleChoiceField): # ORDER BY NULL # """ # qs = Theme.objects.raw(theme_sql) +extra_theme_expo_count = '''SELECT COUNT(`exposition_exposition_theme`.`exposition_id`) FROM `exposition_exposition_theme` WHERE (`theme_theme`.`id` = `exposition_exposition_theme`.`theme_id`) ''' +extra_theme_conf_count = '''SELECT COUNT(`conference_conference_theme`.`conference_id`) FROM `conference_conference_theme` WHERE (`theme_theme`.`id` = `conference_conference_theme`.`theme_id`) ''' -## 3-й рабочий способ (с родным заполением перевода) -## в ходе поиска, был найден и 4-й рабочий способ используя RawSQL, но он для Django >= 1.8 -## https://docs.djangoproject.com/en/1.9/ref/models/expressions/#raw-sql-expressions -## from django.db.models.expressions import RawSQL -extra_themes_expo_count = ''' -SELECT COUNT(`exposition_exposition_theme`.`exposition_id`) -FROM `exposition_exposition_theme` -WHERE (`theme_theme`.`id` = `exposition_exposition_theme`.`theme_id`) -''' -extra_themes_conf_count = ''' -SELECT COUNT(`conference_conference_theme`.`conference_id`) -FROM `conference_conference_theme` -WHERE (`theme_theme`.`id` = `conference_conference_theme`.`theme_id`) -''' -extra_themes_select = { - 'e_count': extra_themes_expo_count, - 'c_count': extra_themes_conf_count, -} -themes = Theme.objects.language('ru').extra(select=extra_themes_select) - +extra_tag_expo_count = '''SELECT COUNT(`exposition_exposition_tag`.`exposition_id`) FROM `exposition_exposition_tag` WHERE (`theme_tag`.`id` = `exposition_exposition_tag`.`tag_id`) ''' +extra_tag_conf_count = '''SELECT COUNT(`conference_conference_tag`.`conference_id`) FROM `conference_conference_tag` WHERE (`theme_tag`.`id` = `conference_conference_tag`.`tag_id`) ''' class FilterForm(forms.Form): TYPES = EnumChoices( @@ -99,28 +83,82 @@ class FilterForm(forms.Form): model = forms.TypedMultipleChoiceField(label=_(u'Тип события'), coerce=int, choices=TYPES, required=False, widget=forms.CheckboxSelectMultiple()) theme = CountModelMultipleChoiceField(label=_(u'Тематики'), - queryset=themes, + queryset=Theme.objects.none(), + required=False, widget=forms.CheckboxSelectMultiple()) + tag = CountModelMultipleChoiceField(label=_(u'Теги'), + queryset=Tag.objects.none(), required=False, widget=forms.CheckboxSelectMultiple()) - # tag = CountModelMultipleChoiceField(label=_(u'Теги'), - # queryset=Tag.active.all()\ - # .annotate(e_count=Count('exposition_tags'), c_count=Count('conference_tags')), - # required=False, widget=forms.CheckboxSelectMultiple()) - - def get_models(self): - val = self.cleaned_data.get('model') - models = [] - if val: + def __init__(self, *args, **kwargs): + super(FilterForm, self).__init__(*args, **kwargs) + self._is_valid = False + self._models = None + self.fields['theme'].queryset = self.get_theme_choices() + self.fields['tag'].queryset = self.get_tag_choices() + + def is_valid(self): + # if getattr(self, '_is_valid', None) is None: + self._is_valid = super(FilterForm, self).is_valid() + + # нам нужно сбрасывать сохраненные модели, + # т.к. после валидации нужно вернуть только выбранные + self._models = None + return self._is_valid + + @property + def models(self): + if self._models is None and self._is_valid: + val = self.cleaned_data.get('model') + self._models = [] if self.TYPES.EXPO in val: - models.append(Exposition) + self._models.append(Exposition) if self.TYPES.CONF in val: - models.append(Conference) - else: - models = [Conference, Exposition] - return models + self._models.append(Conference) + return self._models or [Exposition, Conference] + + def get_theme_choices(self): + # 3-й рабочий способ (с родным заполением перевода) + # в ходе поиска решения, был найден и 4-й рабочий способ используя RawSQL, но он для Django >= 1.8 + # https://docs.djangoproject.com/en/1.9/ref/models/expressions/#raw-sql-expressions + # from django.db.models.expressions import RawSQL + + if getattr(self, '_theme_choices', None) is None: + if Exposition in self.models and Conference in self.models: + count_query = '({q1}) + ({q2})'.format( + q1=extra_theme_expo_count, + q2=extra_theme_conf_count) + filter_types = Q(types=Theme.types.conference) | Q(types=Theme.types.exposition) + elif Exposition in self.models: + count_query = extra_theme_expo_count + filter_types = Q(types=Theme.types.exposition) + elif Conference in self.models: + count_query = extra_theme_conf_count + filter_types = Q(types=Theme.types.conference) + + self._theme_choices = Theme.objects.language()\ + .filter(filter_types)\ + .extra(select={'count': count_query})\ + .order_by('-count', '-name') + return self._theme_choices + + def get_tag_choices(self): + extra_tag_select = {} + if getattr(self, '_tag_choices', None) is None: + if Exposition in self.models and Conference in self.models: + count_query = '({q1}) + ({q2})'.format( + q1=extra_tag_expo_count, + q2=extra_tag_conf_count) + elif Exposition in self.models: + count_query = extra_tag_expo_count + elif Conference in self.models: + count_query = extra_tag_conf_count + self._tag_choices = Tag.objects.language()\ + .extra(select={'count': count_query})\ + .order_by('-count', '-name') + return self._tag_choices def filter(self): - qs = self.default_filter(self.get_models()) + qs = self.default_filter() d = self.cleaned_data if d.get('theme'): qs = qs.filter(theme__in=d.get('theme')) @@ -128,9 +166,17 @@ class FilterForm(forms.Form): qs = qs.filter(tag__in=d.get('tag')) return qs - def default_filter(self, models=None): - qs = RelatedSearchQuerySet().models(Exposition, Conference).load_all() - models = models or [Exposition, Conference] - for model in models: - qs = qs.load_all_queryset(model, model.enable.all()) + def default_filter(self): + qs = RelatedSearchQuerySet().models(*self.models).load_all() + for model in self.models: + qs = qs.load_all_queryset(model, + model.enable.all() + # не реализовано в hvad <_< + # .only( + # 'canceled', 'name', 'main_title', 'expohit', 'logo', + # 'quality_label', 'services', 'visitors', 'members', + # 'data_begin', 'data_end', 'country__url', 'country__name', + # 'city__url', 'place__name' + # ) + ) return qs diff --git a/proj/views.py b/proj/views.py index 4143f35e..afca73ad 100644 --- a/proj/views.py +++ b/proj/views.py @@ -44,7 +44,9 @@ def expo_context(request): 'blogs': Article.objects.every_page_blogs(), 'news_list': Article.objects.main_page_news(), 'sng_countries': settings.SNG_COUNTRIES, 'seo_text': add_seo(request), 'announce_subscribe': SubscribeAssideForm(), - 'NO_EXTERNAL_JS': getattr(settings, 'NO_EXTERNAL_JS', False)} + 'NO_EXTERNAL_JS': getattr(settings, 'NO_EXTERNAL_JS', False), + 'NO_BANNERS': getattr(settings, 'NO_BANNERS', False), + } user = request.user if not user.is_anonymous() and not user.url: diff --git a/templates/client/blank.html b/templates/client/blank.html index 2b68d46f..68be1c4f 100644 --- a/templates/client/blank.html +++ b/templates/client/blank.html @@ -63,27 +63,29 @@ This template include basic anf main styles and js files, "year": "{{ year.text }}", }; - - + {% if not NO_BANNERS %} + + + {% endif %} {% if request.GET.debug == '1' %} diff --git a/templates/client/includes/banners/tops_head_js.html b/templates/client/includes/banners/tops_head_js.html index 273528ca..169a351f 100644 --- a/templates/client/includes/banners/tops_head_js.html +++ b/templates/client/includes/banners/tops_head_js.html @@ -1,13 +1,16 @@ {% load static %} - - + +{% if not NO_BANNERS %} + + +{% endif %} diff --git a/templates/client/includes/events/filter_result.html b/templates/client/includes/events/filter_result.html index 0a276170..bed6bb08 100644 --- a/templates/client/includes/events/filter_result.html +++ b/templates/client/includes/events/filter_result.html @@ -17,7 +17,7 @@ {% endif %}