我找到了一个邪恶的答案:
-
创建
Container
中的指针
Parent
以及
Child
并保持同步。
-
使用
select_subclasses()
从…起
django-model-utils
以填充
parent_list
所有不同的
小孩
物体。
-
包装,包装
QuerySet
's
_prefetch_related_objects
因此,在原始调用之后,子对象被拆分到各自的存储桶中
_prefetched_objects_cache
-
包装,包装
查询集
的
_clone
功能,以便重新包装
_prefetch_related_objects()
每次
查询集
是
_clone()
'天
# get all the subclasses of the `Parent` type
# from http://stackoverflow.com/a/408465/20712
def find_subclasses(module, clazz):
return [
cls
for name, cls in inspect.getmembers(module)
if inspect.isclass(cls) and issubclass(cls, clazz)
]
parent_subclasses = find_subclasses(app.models,Parent)
parent_subclass_2_related_name = {}
for c in parent_subclasses:
try:
parent_subclass_2_related_name[c.__name__] = c.container.field.rel.related_name
except (AttributeError):
pass
# define the query and selectively wrapper it
qs = Container.objects.all()\
.prefetch_related(Prefetch('parent_list',Parent.objects.select_subclasses()))
def attach_clone(obj):
original_clone = obj._clone
def new_clone(*args,**kwargs):
result = original_clone(*args,**kwargs)
attach_clone(result) # re-wrapper _clone
old_prefetch = result._prefetch_related_objects
def new_prefetch(*args):
old_prefetch()
for obj in result._result_cache:
for s in obj._prefetched_objects_cache['parent_list']:
obj._prefetched_objects_cache.setdefault(parent_subclass_2_related_name[s.__class__.__name__],[]).append(s)
result._prefetch_related_objects = new_prefetch
return result
obj._clone = new_clone
attach_clone(qs)
return qs