You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.5 KiB
92 lines
3.5 KiB
# -*- coding: utf-8 -*-
|
|
|
|
from itertools import chain
|
|
|
|
from django import forms
|
|
from django.utils.translation import ugettext as _
|
|
from django.utils.encoding import force_text
|
|
from django.utils.html import format_html
|
|
from django.utils.safestring import mark_safe
|
|
from django.db.models import Count, Sum
|
|
|
|
from haystack.query import SearchQuerySet
|
|
|
|
from functions.model_utils import EnumChoices
|
|
from exposition.models import Exposition
|
|
from conference.models import Conference
|
|
from theme.models import Theme, Tag
|
|
|
|
|
|
class CheckboxSelectMultiple(forms.CheckboxSelectMultiple):
|
|
def render(self, name, value, attrs=None, choices=()):
|
|
if value is None: value = []
|
|
has_id = attrs and 'id' in attrs
|
|
final_attrs = self.build_attrs(attrs, name=name)
|
|
output = ['<ul>']
|
|
# Normalize to strings
|
|
str_values = set([force_text(v) for v in value])
|
|
for i, (option_value, option_label) in enumerate(chain(self.choices, choices)):
|
|
# If an ID attribute was given, add a numeric index as a suffix,
|
|
# so that the checkboxes don't all have the same ID attribute.
|
|
if has_id:
|
|
final_attrs = dict(final_attrs, id='%s_%s' % (attrs['id'], i))
|
|
label_for = format_html(u' for="{0}"', final_attrs['id'])
|
|
else:
|
|
label_for = ''
|
|
|
|
cb = forms.CheckboxInput(final_attrs, check_test=lambda value: value in str_values)
|
|
option_value = force_text(option_value)
|
|
rendered_cb = cb.render(name, option_value)
|
|
option_label = force_text(option_label)
|
|
count = 763
|
|
output.append(format_html(u'<li><label{0}>{1} {2} ({count})</label></li>',
|
|
label_for, rendered_cb, option_label,
|
|
count=count))
|
|
output.append('</ul>')
|
|
return mark_safe('\n'.join(output))
|
|
|
|
|
|
class FilterForm(forms.Form):
|
|
# class Meta:
|
|
# widgets = {
|
|
# 'model': forms.CheckboxSelectMultiple(),
|
|
# 'theme': forms.CheckboxSelectMultiple(),
|
|
# 'tag': forms.CheckboxSelectMultiple(),
|
|
# }
|
|
|
|
TYPES = EnumChoices(
|
|
EXPO=(1, _(u'Выставки')),
|
|
CONF=(2, _(_(u'Конференции'))),
|
|
)
|
|
|
|
model = forms.TypedMultipleChoiceField(label=_(u'Тип события'), coerce=int, choices=TYPES, required=False, widget=CheckboxSelectMultiple())
|
|
theme = forms.ModelMultipleChoiceField(label=_(u'Тематики'),
|
|
queryset=Theme.active.all()\
|
|
.annotate(e_count=Count('exposition_themes'), c_count=Count('conference_themes')),
|
|
required=False, widget=CheckboxSelectMultiple())
|
|
tag = forms.ModelMultipleChoiceField(label=_(u'Теги'),
|
|
queryset=Tag.active.all()\
|
|
.annotate(e_count=Count('exposition_themes'), c_count=Count('conference_themes')),
|
|
required=False, widget=CheckboxSelectMultiple())
|
|
|
|
|
|
def get_models(self):
|
|
val = self.cleaned_data.get('model')
|
|
models = []
|
|
if val:
|
|
if self.TYPES.EXPO in val:
|
|
models.append(Exposition)
|
|
if self.TYPES.CONF in val:
|
|
models.append(Conference)
|
|
else:
|
|
models = [Conference, Exposition]
|
|
return models
|
|
|
|
def filter(self):
|
|
qs = SearchQuerySet().models(*self.get_models()).all()
|
|
d = self.cleaned_data
|
|
if d.get('theme'):
|
|
qs = qs.filter(theme__in=d.get('theme'))
|
|
if d.get('tag'):
|
|
qs = qs.filter(tag__in=d.get('tag'))
|
|
return qs
|
|
|