|
|
|
|
@ -1,26 +1,74 @@ |
|
|
|
|
# -*- 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(), |
|
|
|
|
# } |
|
|
|
|
# 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=forms.CheckboxSelectMultiple()) |
|
|
|
|
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') |
|
|
|
|
@ -37,4 +85,8 @@ class FilterForm(forms.Form): |
|
|
|
|
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 |
|
|
|
|
|