работа над фильтрами

remotes/origin/stage5
Alexander Burdeiny 10 years ago
parent b140654443
commit 74aac56557
  1. 93
      events/forms.py
  2. 4
      place_conference/search_indexes.py
  3. 2
      templates/c_admin/newsletters/popup_count.html
  4. 2
      templates/client/includes/events/filter_form.html
  5. 1
      templates/client/search/indexes/place_conference/placeconference_text.txt

@ -152,6 +152,7 @@ class FilterForm(forms.Form):
self._is_valid = False
self._models = None
self._lookup_kwargs = None
self.lang = get_language()
# self.selected_filter_data = {}
# self.fields['theme'].queryset = self.get_theme_choices()
# self.fields['tag'].queryset = self.get_tag_choices()
@ -245,7 +246,7 @@ class FilterForm(forms.Form):
'country_id__in': d.get('country'),
}
if d.get('city'):
self._lookup_kwargs['country'] = {
self._lookup_kwargs['city'] = {
'city_id__in': d.get('city'),
}
return self._lookup_kwargs
@ -276,8 +277,21 @@ class FilterForm(forms.Form):
# field_qs = (x.id.split('.')[1:] for x in self.filter(qs=field_qs, lookup_kwargs=field_lookup_kwargs) if x.id)
# if field == 'theme':
# self.fields[field].queryset = self.get_theme_choices(field_qs)
self.fields[field].queryset = self.fields[field].queryset.extra(
select=self.make_count_select(field, field_lookup_kwargs)).values('pk', 'name', 'count')
values = ['pk', 'name']
order_by = []
select = self.make_count_select(field, field_lookup_kwargs)
qs = self.fields[field].queryset
for key in select.iterkeys():
values.append(key)
if key == 'selected':
order_by.insert(0, '-' + key)
else:
order_by.append('-' + key)
qs = qs.extra(select=select)
self.fields[field].queryset = qs\
.values(*values)\
.order_by(*order_by)
print(self.fields[field].queryset.query)
for field in self.fields:
@ -285,8 +299,13 @@ class FilterForm(forms.Form):
if hasattr(field, 'queryset'):
field.queryset = field.queryset[:15]
def make_ids_in_sql_format(self, values):
return tuple(values) if len(values) > 1 else '({})'.format(*values)
def make_count_select(self, field, lookup_kwargs):
count_selects = []
case = None
count = None
print('looking {} {}'.format(field, lookup_kwargs))
for model in self.models:
_field, _model, direct, m2m = model._meta.get_field_by_name(field)
@ -302,27 +321,41 @@ class FilterForm(forms.Form):
'db_table': model._meta.db_table,
'm2m_reverse_name': _field.m2m_reverse_name(),
'm2m_rel_to_table': _field.rel.to._meta.db_table,
'lang': self.lang,
}
select = \
'''SELECT COUNT(`{m2m_db_table}`.`{m2m_column_name}`) FROM `{m2m_db_table}` INNER JOIN `{db_table}` ON (`{m2m_db_table}`.`{m2m_column_name}` = `{db_table}`.`id`) '''\
.format(**format_kwargs)
where.append(
''' (`{m2m_rel_to_table}_translation`.`master_id` = `{m2m_db_table}`.`{m2m_reverse_name}`) '''.format(**format_kwargs)
''' (`{m2m_rel_to_table}_translation`.`master_id` = `{m2m_db_table}`.`{m2m_reverse_name}`) AND `{m2m_rel_to_table}_translation`.`language_code` = '{lang}' AND `{db_table}`.`is_published` = True '''.format(**format_kwargs)
)
# ForeignKey
elif not m2m and direct and isinstance(_field, ForeignKey):
format_kwargs = {
_format_kwargs = {
'attname': _field.column,
'db_table': model._meta.db_table,
'rel_db_table': _field.rel.to._meta.db_table,
'lang': self.lang,
# 'attname': _field.related.field.get_attname(),
}
select = \
'''SELECT COUNT(`{db_table}`.`id`) FROM `{rel_db_table}` LEFT OUTER JOIN `{db_table}` ON (`{rel_db_table}`.`id` = `{db_table}`.`{attname}`)'''\
.format(**format_kwargs)
group_by = ''' GROUP BY `{rel_db_table}`.`id` '''.format(**format_kwargs)
'''SELECT COUNT(`{db_table}`.`{attname}`) FROM `{db_table}`'''\
.format(**_format_kwargs)
# '''SELECT COUNT(`{db_table}`.`id`) FROM `{rel_db_table}` LEFT OUTER JOIN `{db_table}` ON (`{rel_db_table}`.`id` = `{db_table}`.`{attname}`)'''\
where.append(
''' `{db_table}`.`{attname}` = `{rel_db_table}_translation`.`master_id` AND `{rel_db_table}_translation`.`language_code` = '{lang}' AND `{db_table}`.`is_published` = True '''\
.format(**_format_kwargs))
group_by = ''' GROUP BY `{rel_db_table}_translation`.`master_id` '''.format(**_format_kwargs)
# mark selected items (for ordering)
if case is None and field in self.lookup_kwargs.keys():
values = self.lookup_kwargs[field].values()[0]
case = \
''' CASE WHEN `{table}`.`master_id` in {ids} THEN 1 ELSE 0 END '''.format(
table=self.fields[field].queryset.model._meta.db_table,
ids=self.make_ids_in_sql_format(values))
# joins and where lookups
for l_field, lookups in lookup_kwargs.iteritems():
@ -334,7 +367,7 @@ class FilterForm(forms.Form):
'm2m_column_name': _l_field.m2m_column_name(),
'db_table': model._meta.db_table,
'm2m_reverse_name': _l_field.m2m_reverse_name(),
'ids': tuple(values) if len(values) > 1 else '({})'.format(*values),
'ids': self.make_ids_in_sql_format(values),
}
joins.append(
''' INNER JOIN `{m2m_db_table}` ON (`{db_table}`.`id` = `{m2m_db_table}`.`{m2m_column_name}`)'''\
@ -346,38 +379,63 @@ class FilterForm(forms.Form):
_format_kwargs = {
'db_table': model._meta.db_table,
'attname': _l_field.column,
'ids': tuple(values) if len(values) > 1 else '({})'.format(*values),
'ids': self.make_ids_in_sql_format(values),
}
where.append(
'''`{db_table}`.`{attname}` IN {ids}'''\
.format(**_format_kwargs))
count_selects.append(select + ''.join(joins) + ' where ' + ' and '.join(where) + group_by)
# case selected
# todo
if len(count_selects) == 2:
count = '({}) + ({})'.format(*count_selects)
elif len(count_selects) == 1:
count = count_selects[0]
else:
return {}
return {'count': count}
d = {}
if case is not None:
d['selected'] = case
if count:
d['count'] = count
return d
'''
SELECT
`city_city_translation`.`master_id`,
`<city_city_translation></city_city_translation>`.`name`,
COUNT(`conference_conference`.`id`) AS `count`
FROM
`city_city`
`city_city_translation`
LEFT OUTER JOIN
`city_city` ON (`city_city_translation`.`master_id` = `city_city`.`id`)
LEFT OUTER JOIN
`conference_conference` ON (`city_city`.`id` = `conference_conference`.`city_id`)
LEFT OUTER JOIN
`conference_conference_tag` ON (`conference_conference`.`id` = `conference_conference_tag`.`conference_id`)
WHERE
`conference_conference_tag`.`tag_id` IN (469 , 832, 366, 922)
GROUP BY `city_city`.`id`
GROUP BY `city_city_translation`.`language_code` , `city_city_translation`.`master_id`
ORDER BY NULL
'''
'''
SELECT
(SELECT
COUNT(`exposition_exposition`.`country_id`)
FROM
`exposition_exposition`
INNER JOIN
`exposition_exposition_theme` ON (`exposition_exposition`.`id` = `exposition_exposition_theme`.`exposition_id`)
where
`exposition_exposition_theme`.`theme_id` IN (1, 2, 3)
and `exposition_exposition`.`country_id` = `country_country_translation`.`master_id`
GROUP BY `country_country_translation`.`master_id`) AS `count`,
`country_country_translation`.`master_id`,
`country_country_translation`.`name`
FROM
`country_country_translation`
'''
'''
SELECT
@ -409,5 +467,4 @@ WHERE
OR `theme_theme`.`types` = (`theme_theme`.`types` | 2))
AND (`theme_theme_translation`.`language_code` = 'ru')
order BY `selected` DESC , `count` DESC
'''

@ -11,12 +11,12 @@ class PlaceExpositionIndex(indexes.SearchIndex, indexes.Indexable):
def prepare_country(self, obj):
if obj.country:
return '%s'%obj.country.id
return '%s'%obj.country_id
return ''
def prepare_city(self, obj):
if obj.city:
return '%s'%obj.country.city
return '%s'%obj.city_id
return ''
def prepare_where(self, obj):

@ -10,7 +10,7 @@
{% block body %}
<div class="box span10">
<div class="box span9">
<div class="box-header well">
<h2><i class="icon-arrow-down"></i>Статистика показов попапов</h2>
</div>

@ -1,7 +1,7 @@
{% load i18n %}
<form action="{% url 'events:main' %}" method="get">
{% csrf_token %}
{# {% csrf_token %} #}
{% for field in form %}
{% if field.errors %}error{% endif %}

Loading…
Cancel
Save