|
|
|
|
@ -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 |
|
|
|
|
|
|
|
|
|
''' |
|
|
|
|
|