1461: Этап №5: Фильтрация событий

сделал подсчет событий в фильтре по типу;
сделал обработку аякс запроса с возвратом результатов и формы в JSONе (HTML)
remotes/origin/stage5
Alexander Burdeiny 10 years ago
parent 0319f44ddd
commit 5d3a2d5266
  1. 8
      conference/views.py
  2. 4
      events/common.py
  3. 34
      events/forms.py
  4. 17
      events/mixin.py
  5. 41
      events/views.py
  6. 9
      exposition/views.py
  7. 1
      templates/client/blank.html

@ -35,11 +35,11 @@ from stats_collector.mixin import (
ObjectStatMixin ObjectStatMixin
) )
from theme.models import Tag, Theme from theme.models import Tag, Theme
from events.mixin import ConfFilterMixin
MONTHES = settings.MONTHES MONTHES = settings.MONTHES
class ConferenceBy(ConfFilterMixin, ConfSectionMixin, JitterCacheMixin, MetadataMixin, ListView):
class ConferenceBy(ConfSectionMixin, JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE cache_range = settings.CACHE_RANGE
template_name = 'client/conference/conference_by.html' template_name = 'client/conference/conference_by.html'
title1 = '' title1 = ''
@ -111,7 +111,7 @@ class ConferenceByCity(ConferenceBy):
# .order_by('translations__name').distinct() # .order_by('translations__name').distinct()
class ConferenceCatalog(ConfSectionKindMixin, JitterCacheMixin, MetadataMixin, ListView): class ConferenceCatalog(ConfFilterMixin, ConfSectionKindMixin, JitterCacheMixin, MetadataMixin, ListView):
cache_range = settings.CACHE_RANGE cache_range = settings.CACHE_RANGE
model = Conference model = Conference
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
@ -429,7 +429,7 @@ class ConferenceDetail(ObjectStatMixin, JitterCacheMixin, MetadataMixin, DetailV
return context return context
class ConferenceList(ConfSectionMixin, MetadataMixin, JitterCacheMixin, ListView): class ConferenceList(ConfFilterMixin, ConfSectionMixin, MetadataMixin, JitterCacheMixin, ListView):
cache_range = settings.CACHE_RANGE cache_range = settings.CACHE_RANGE
model = Conference model = Conference
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION

@ -40,6 +40,10 @@ def get_choices_kwargs(mapping):
MEMBERS = EnumChoices(**get_choices_kwargs(members_mapping)) MEMBERS = EnumChoices(**get_choices_kwargs(members_mapping))
VISITORS = EnumChoices(**get_choices_kwargs(visitors_mapping)) VISITORS = EnumChoices(**get_choices_kwargs(visitors_mapping))
PRICE = EnumChoices(**get_choices_kwargs(price_mapping)) PRICE = EnumChoices(**get_choices_kwargs(price_mapping))
TYPES = EnumChoices(
EXPO=(1, _(u'Выставки')),
CONF=(2, _(_(u'Конференции'))),
)
class ExtraWhere(object): class ExtraWhere(object):

@ -25,7 +25,7 @@ from conference.models import Conference
from theme.models import Theme, Tag from theme.models import Theme, Tag
from country.models import Country from country.models import Country
from city.models import City from city.models import City
from events.common import MEMBERS, VISITORS, PRICE from events.common import MEMBERS, VISITORS, PRICE, TYPES
from events.common import members_mapping, visitors_mapping, price_mapping from events.common import members_mapping, visitors_mapping, price_mapping
from events.common import ExtraWhere, OR, AND from events.common import ExtraWhere, OR, AND
@ -120,14 +120,11 @@ values_mapping = {
class FilterForm(forms.Form): class FilterForm(forms.Form):
TYPES = EnumChoices( # TYPES = TYPES
EXPO=(1, _(u'Выставки')),
CONF=(2, _(_(u'Конференции'))),
)
# MEMBERS = MEMBERS # MEMBERS = MEMBERS
# VISITORS = VISITORS # VISITORS = VISITORS
# PRICE = PRICE # PRICE = PRICE
model = FilterTypedMultipleChoiceField( event_type = FilterTypedMultipleChoiceField(
label=_(u'Тип события'), coerce=int, label=_(u'Тип события'), coerce=int,
choices=TYPES, required=False, widget=FilterCheckboxSelectMultiple()) choices=TYPES, required=False, widget=FilterCheckboxSelectMultiple())
theme = CountModelMultipleChoiceField( theme = CountModelMultipleChoiceField(
@ -183,11 +180,11 @@ class FilterForm(forms.Form):
@property @property
def models(self): def models(self):
if self._models is None and self._is_valid: if self._models is None and self._is_valid:
val = self.cleaned_data.get('model') val = self.cleaned_data.get('event_type')
self._models = [] self._models = []
if self.TYPES.EXPO in val: if TYPES.EXPO in val:
self._models.append(Exposition) self._models.append(Exposition)
if self.TYPES.CONF in val: if TYPES.CONF in val:
self._models.append(Conference) self._models.append(Conference)
return self._models or [Exposition, Conference] return self._models or [Exposition, Conference]
@ -223,13 +220,14 @@ class FilterForm(forms.Form):
def filter(self, qs=None): def filter(self, qs=None):
qs = qs or self.default_filter() qs = qs or self.default_filter()
# lookup_kwargs = dict(ChainMap({}, *(lookup_kwargs or self.lookup_kwargs).values())) # lookup_kwargs = dict(ChainMap({}, *(lookup_kwargs or self.lookup_kwargs).values()))
return qs.filter(**self.lookup_kwargs) return qs.filter(**self.lookup_kwargs).order_by('data_begin')
def default_filter(self, load_all=True): def default_filter(self, load_all=True, _models=None):
qs = RelatedSearchQuerySet().models(*self.models) models = _models or self.models
qs = RelatedSearchQuerySet().models(*models)
if load_all: if load_all:
qs = qs.load_all() qs = qs.load_all()
for model in self.models: for model in models:
qs = qs.load_all_queryset(model, model.enable.all()) qs = qs.load_all_queryset(model, model.enable.all())
qs = qs.filter(data_end__gte=datetime.now()) qs = qs.filter(data_end__gte=datetime.now())
return qs return qs
@ -270,11 +268,21 @@ class FilterForm(forms.Form):
for field in ['members', 'visitors', 'price']: for field in ['members', 'visitors', 'price']:
self.fields[field].choices = self.make_local_field_count(field) or self.fields[field].choices self.fields[field].choices = self.make_local_field_count(field) or self.fields[field].choices
self.make_event_type_choices_count()
# for field in self.fields: # for field in self.fields:
# field = self.fields[field] # field = self.fields[field]
# if hasattr(field, 'queryset'): # if hasattr(field, 'queryset'):
# field.queryset = field.queryset[:15] # field.queryset = field.queryset[:15]
def make_event_type_choices_count(self):
types = {1: Exposition, 2: Conference}
choices = []
for _type, label in TYPES:
qs = self.default_filter(load_all=False, _models=[types.get(_type)])
count = qs.filter(**self.lookup_kwargs).count()
choices.append((_type, label + ' <i>({count})</i>'.format(count=count)))
self.fields['event_type'].choices = choices
def make_ids_in_sql_format(self, values): def make_ids_in_sql_format(self, values):
return tuple(values) if len(values) > 1 else '({})'.format(*values) return tuple(values) if len(values) > 1 else '({})'.format(*values)

@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
from .common import TYPES
class BaseFilterMixin(object):
def get_context_data(self, **kwargs):
context = super(BaseFilterMixin, self).get_context_data(**kwargs)
context['event_type'] = self.event_type
return context
class ConfFilterMixin(BaseFilterMixin):
event_type = TYPES.CONF
class ExpoFilterMixin(BaseFilterMixin):
event_type = TYPES.EXPO

@ -1,11 +1,14 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.views.generic.edit import FormMixin from django.views.generic.edit import FormMixin
from django.conf import settings from django.conf import settings
from django.template.loader import render_to_string
from haystack.query import SearchQuerySet from haystack.query import SearchQuerySet
from functions.custom_views import ContextMixin from functions.custom_views import ContextMixin
from functions.custom_views import ListView from functions.custom_views import ListView
from functions.http import JsonResponse
from exposition.models import Exposition from exposition.models import Exposition
from conference.models import Conference from conference.models import Conference
@ -17,7 +20,8 @@ class FilterListView(ContextMixin, FormMixin, ListView):
form_class = FilterForm form_class = FilterForm
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
_template_name = 'events/filter_listview.html' _template_name = 'events/filter_listview.html'
_template_name_ajax = 'events/filter_listview_ajax.html' _ajax_results_template_name = 'events/filter_listview_ajax.html'
_ajax_form_template_name = 'includes/events/filter_form.html'
def get_form_kwargs(self): def get_form_kwargs(self):
kwargs = super(FilterListView, self).get_form_kwargs() kwargs = super(FilterListView, self).get_form_kwargs()
@ -30,21 +34,40 @@ class FilterListView(ContextMixin, FormMixin, ListView):
else: else:
qs = self.form.default_filter() qs = self.form.default_filter()
self.form.recalculate_choices() self.form.recalculate_choices()
# import pdb; pdb.set_trace()
return qs return qs
def handle_ajax(request, *args, **kwargs):
self.template_name =
handle_ajax
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.form = self.get_form(self.get_form_class()) self.form = self.get_form(self.get_form_class())
self.extra_ctx['form'] = self.form self.extra_ctx['form'] = self.form
self.template_name = self._template_name
# get params for paginator # ajax
get = request.GET.copy() if request.is_ajax():
if 'page' in get: self.template_name = self._ajax_results_template_name
del get['page'] data = {
self.extra_ctx['GETparams'] = get.urlencode() 'success': True,
'results': super(FilterListView, self).get(request, *args, **kwargs),
# ajax or get 'form': render_to_string(self._ajax_form_template_name, {'form': self.form}),
self.template_name = self._template_name_ajax if request.is_ajax() else self._template_name }
return JsonResponse(data)
# usual get
return super(FilterListView, self).get(request, *args, **kwargs) return super(FilterListView, self).get(request, *args, **kwargs)
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs) return self.get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(FilterListView, self).get_context_data(**kwargs)
# get params for paginator
get = self.request.GET.copy()
if 'page' in get:
del get['page']
self.context['GETparams'] = get.urlencode()
return context

@ -36,9 +36,10 @@ from stats_collector.mixin import (
ObjectStatMixin ObjectStatMixin
) )
from theme.models import Tag, Theme from theme.models import Tag, Theme
from events.mixin import ExpoFilterMixin
class ExpositionBy(ExpoSectionMixin, JitterCacheMixin, MetadataMixin, ListView): class ExpositionBy(ExpoFilterMixin, ExpoSectionMixin, JitterCacheMixin, MetadataMixin, ListView):
template_name = 'exposition/exposition_by.html' template_name = 'exposition/exposition_by.html'
title1 = '' title1 = ''
title2 = '' title2 = ''
@ -113,7 +114,7 @@ class ExpositionByCity(ExpositionBy):
# .order_by('translations__name').distinct() # .order_by('translations__name').distinct()
class ExpositionSearchView(ExpoSearchView): class ExpositionSearchView(ExpoFilterMixin, ExpoSearchView):
#paginate_by = 10 #paginate_by = 10
template_name = 'client/exposition/search.html' template_name = 'client/exposition/search.html'
search_form = ExpositionSearchForm search_form = ExpositionSearchForm
@ -324,7 +325,7 @@ class ExpositionServiceView(JitterCacheMixin, MetadataMixin, FormMixin, DetailVi
return self.initial.copy() return self.initial.copy()
class ExpoList(ExpoSectionMixin, MetadataMixin, JitterCacheMixin, ListView): class ExpoList(ExpoFilterMixin, ExpoSectionMixin, MetadataMixin, JitterCacheMixin, ListView):
cache_range = [60*30, 60*60] cache_range = [60*30, 60*60]
model = Exposition model = Exposition
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
@ -360,7 +361,7 @@ class ExpoList(ExpoSectionMixin, MetadataMixin, JitterCacheMixin, ListView):
return context return context
class ExpoCatalog(ExpoSectionKindMixin, JitterCacheMixin, MetadataMixin, ListView): class ExpoCatalog(ExpoFilterMixin, ExpoSectionKindMixin, JitterCacheMixin, MetadataMixin, ListView):
model = Exposition model = Exposition
paginate_by = settings.CLIENT_PAGINATION paginate_by = settings.CLIENT_PAGINATION
template_name = 'client/exposition/catalog.html' template_name = 'client/exposition/catalog.html'

@ -61,6 +61,7 @@ This template include basic anf main styles and js files,
"tag": "{{ tag }}", "tag": "{{ tag }}",
"month": "{{ month.slug }}", "month": "{{ month.slug }}",
"year": "{{ year.text }}", "year": "{{ year.text }}",
"event_type": "{{ event_type }}",
}; };
</script> </script>
{% if not NO_BANNERS %} {% if not NO_BANNERS %}

Loading…
Cancel
Save