add QuerySetWrapper support for reverse m2m __in filtering
This commit is contained in:
parent
1fb37eb41b
commit
e7292692d5
1 changed files with 41 additions and 0 deletions
|
@ -370,9 +370,50 @@ class BaseQueryWrapper(BaseWrapper):
|
||||||
|
|
||||||
filter_type = segments.pop(0)
|
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:
|
if filter_type == class_value.field.model._meta.pk.name:
|
||||||
filter_type = 'pk'
|
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:
|
if segments:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue