support for reverse manytomany lookups in QuerySetsWrapper
This commit is contained in:
parent
de930722cb
commit
aa0843fb24
1 changed files with 28 additions and 8 deletions
|
@ -4,7 +4,7 @@ from itertools import chain
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import Manager, Prefetch, Q
|
from django.db.models import Manager, Prefetch, Q
|
||||||
from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor
|
from django.db.models.fields.related_descriptors import ForwardManyToOneDescriptor, ManyToManyDescriptor
|
||||||
from django.db.models.query_utils import DeferredAttribute
|
from django.db.models.query_utils import DeferredAttribute
|
||||||
|
|
||||||
|
|
||||||
|
@ -332,6 +332,32 @@ class BaseQueryWrapper(BaseWrapper):
|
||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
if isinstance(class_value, ManyToManyDescriptor):
|
||||||
|
print(class_value.__dict__)
|
||||||
|
if not segments:
|
||||||
|
filter_name = field_name + '__pk'
|
||||||
|
filter_value = filter_value.pk
|
||||||
|
segments = ['pk']
|
||||||
|
q = Q(**{filter_name: filter_value})
|
||||||
|
|
||||||
|
filter_type = segments.pop(0)
|
||||||
|
|
||||||
|
if filter_type == class_value.field.model._meta.pk.name:
|
||||||
|
filter_type = 'pk'
|
||||||
|
|
||||||
|
if segments:
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
if filter_type == 'pk':
|
||||||
|
if class_value.reverse:
|
||||||
|
model = class_value.field.model
|
||||||
|
return ((q & ~Q(pk__in=self._changeset.m2m_remove_existing.get(model, {}).get(filter_value, ()))) |
|
||||||
|
Q(pk__in=self._changeset.m2m_add_existing.get(model, {}).get(filter_value, ())))
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
if isinstance(class_value, DeferredAttribute):
|
if isinstance(class_value, DeferredAttribute):
|
||||||
if not segments:
|
if not segments:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -447,13 +473,7 @@ class ManyRelatedManagerWrapper(RelatedManagerWrapper):
|
||||||
self._changeset.add_m2m_remove(self._obj.instance, name=self._get_cache_name(), value=pk, author=author)
|
self._changeset.add_m2m_remove(self._obj.instance, name=self._get_cache_name(), value=pk, author=author)
|
||||||
|
|
||||||
def all(self):
|
def all(self):
|
||||||
# todo: this filtering is temporary as long as querysets do not filter themselves according to changes
|
return self.model.objects.filter(**self._obj.core_filters)
|
||||||
filter_ = Q(**self._obj.core_filters)
|
|
||||||
model = type(self._obj.instance)
|
|
||||||
instance_pk = self._obj.instance.pk
|
|
||||||
filter_ &= ~Q(pk__in=self._changeset.m2m_remove_existing.get(model, {}).get(instance_pk, ()))
|
|
||||||
filter_ |= Q(pk__in=self._changeset.m2m_add_existing.get(model, {}).get(instance_pk, ()))
|
|
||||||
return self.model.objects.filter(filter_)
|
|
||||||
|
|
||||||
|
|
||||||
class QuerySetWrapper(BaseQueryWrapper):
|
class QuerySetWrapper(BaseQueryWrapper):
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue