add QuerySetWrapper support for reverse m2m __in filtering

This commit is contained in:
Laura Klünder 2017-06-17 19:42:17 +02:00
parent 1fb37eb41b
commit e7292692d5

View file

@ -370,9 +370,50 @@ class BaseQueryWrapper(BaseWrapper):
filter_type = segments.pop(0)
if not segments and filter_type == 'in':
filter_name = field_name+'__pk__in'
filter_value = tuple(obj.pk for obj in filter_value)
filter_type = 'pk'
segments = ['in']
q = Q(**{filter_name: filter_value})
if filter_type == class_value.field.model._meta.pk.name:
filter_type = 'pk'
if filter_type == 'pk' and segments == ['in']:
if not class_value.reverse:
raise NotImplementedError
# so... e.g. we want to get all groups that belong to one of the given spaces.
# field_name would be "spaces"
model = class_value.field.model # space
filter_value = set(filter_value) # space pks
filter_value_existing = set(pk for pk in filter_value if not self.is_created_pk(pk))
# get spaces that we are interested about that had groups added or removed
m2m_added = {pk: val[field_name] for pk, val in self._changeset.m2m_added.get(model, {}).items()
if pk in filter_value and field_name in val}
m2m_removed = {pk: val[field_name] for pk, val in self._changeset.m2m_removed.get(model, {}).items()
if pk in filter_value and field_name in val} # can only be existing spaces
# directly lookup groups for spaces that had no groups removed
q = Q(**{field_name+'__pk__in': filter_value_existing - set(m2m_removed.keys())})
# lookup groups for spaces that had groups removed
for pk, values in m2m_removed.items():
q |= Q(Q(**{field_name + '__pk': pk}) & ~Q(pk__in=values))
# get pk of groups that were added to any of the spaces
r_added_pks = reduce(operator.or_, m2m_added.values(), set())
# lookup existing groups that were added to any of the spaces
q |= Q(pk__in=tuple(pk for pk in r_added_pks if not self.is_created_pk(pk)))
# get created groups that were added to any of the spaces
created_pks = set(int(pk[1:]) for pk in r_added_pks if self.is_created_pk(pk))
return q, created_pks
if segments:
raise NotImplementedError