add QuerySetWrapper support for reverse m2m __in filtering
@@ -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
