filters work: ForeignKey count added

remotes/origin/stage5
Alexander Burdeiny 10 years ago
parent eb032d5257
commit 630bce9830
  1. 75
      events/forms.py

@ -11,9 +11,8 @@ from django.utils.translation import get_language, ugettext as _
from django.utils.encoding import smart_text, force_text
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.db.models import Count, Sum, Q
from django.db.models import Count, Sum, Q, ForeignKey, ManyToManyField
from django.core.exceptions import ValidationError
from haystack.query import SearchQuerySet, RelatedSearchQuerySet
from functions.model_utils import EnumChoices
@ -267,10 +266,11 @@ class FilterForm(forms.Form):
def recalculate_choices(self):
print(self._is_valid)
if self._is_valid:
for field, val in self.lookup_kwargs.iteritems():
for field in ['theme', 'tag', 'city', 'country']:
field_qs = self.default_filter(load_all=False)
field_lookup_kwargs = self.lookup_kwargs.copy()
del field_lookup_kwargs[field]
if field in field_lookup_kwargs.keys():
del field_lookup_kwargs[field]
# if not field_lookup_kwargs:
# continue
# field_qs = (x.id.split('.')[1:] for x in self.filter(qs=field_qs, lookup_kwargs=field_lookup_kwargs) if x.id)
@ -279,8 +279,6 @@ class FilterForm(forms.Form):
self.fields[field].queryset = self.fields[field].queryset.extra(
select=self.make_count_select(field, field_lookup_kwargs)).values('pk', 'name', 'count')
print(self.fields[field].queryset.query)
# self.make_count_select(field, field_lookup_kwargs)
# print(field_qs)
for field in self.fields:
field = self.fields[field]
@ -292,7 +290,11 @@ class FilterForm(forms.Form):
print('looking {} {}'.format(field, lookup_kwargs))
for model in self.models:
_field, _model, direct, m2m = model._meta.get_field_by_name(field)
if m2m:
joins = []
where = []
group_by = ''
# ManyToManyField
if m2m and direct and isinstance(_field, ManyToManyField):
_field
format_kwargs = {
'm2m_db_table': _field.m2m_db_table(),
@ -305,14 +307,28 @@ class FilterForm(forms.Form):
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)
joins = []
where = [
''' (`{m2m_rel_to_table}_translation`.`master_id` = `{m2m_db_table}`.`{m2m_reverse_name}`) '''.format(**format_kwargs)
]
for l_field, lookups in lookup_kwargs.iteritems():
_l_field, l_model, _direct, _m2m = model._meta.get_field_by_name(l_field)
values = lookups.values()[0]
where.append(
''' (`{m2m_rel_to_table}_translation`.`master_id` = `{m2m_db_table}`.`{m2m_reverse_name}`) '''.format(**format_kwargs)
)
# ForeignKey
elif not m2m and direct and isinstance(_field, ForeignKey):
format_kwargs = {
'attname': _field.column,
'db_table': model._meta.db_table,
'rel_db_table': _field.rel.to._meta.db_table,
# '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)
# joins and where lookups
for l_field, lookups in lookup_kwargs.iteritems():
_l_field, l_model, _direct, _m2m = model._meta.get_field_by_name(l_field)
values = lookups.values()[0]
if _m2m and _direct and isinstance(_l_field, ManyToManyField):
_format_kwargs = {
'm2m_db_table': _l_field.m2m_db_table(),
'm2m_column_name': _l_field.m2m_column_name(),
@ -326,7 +342,16 @@ class FilterForm(forms.Form):
where.append(
'''`{m2m_db_table}`.`{m2m_reverse_name}` IN {ids}'''\
.format(**_format_kwargs))
count_selects.append(select + ''.join(joins) + ' where ' + ' and '.join(where))
elif not m2m and _direct and isinstance(_l_field, ForeignKey):
_format_kwargs = {
'db_table': model._meta.db_table,
'attname': _l_field.column,
'ids': tuple(values) if len(values) > 1 else '({})'.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
@ -334,8 +359,26 @@ class FilterForm(forms.Form):
count = '({}) + ({})'.format(*count_selects)
elif len(count_selects) == 1:
count = count_selects[0]
else:
return {}
return {'count': count}
'''
SELECT
COUNT(`conference_conference`.`id`) AS `count`
FROM
`city_city`
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`
ORDER BY NULL
'''
'''
SELECT
(SELECT

Loading…
Cancel
Save