【发布时间】:2010-12-11 03:44:37
【问题描述】:
我的模型结构如下:
class Container(models.Model):
pass
class Generic(models.Model):
name = models.CharacterField(unique=True)
cont = models.ManyToManyField(Container, null=True)
# It is possible to have a Generic object not associated with any container,
# thats why null=True
class Specific1(Generic):
...
class Specific2(Generic):
...
...
class SpecificN(Generic):
...
比如说,我需要检索所有与特定 Container 有关系的Specific-type 模型。
用于此的 SQL 或多或少是微不足道的,但这不是问题所在。不幸的是,我在使用 ORM(尤其是 Django 的 ORM)方面不是很有经验,所以我可能在这里遗漏了一个模式。
当以蛮力方式完成时,-
c = Container.objects.get(name='somename') # this gets me the container
items = c.generic_set.all()
# this gets me all Generic objects, that are related to the container
# Now what? I need to get to the actual Specific objects, so I need to somehow
# get the type of the underlying Specific object and get it
for item in items:
spec = getattr(item, item.get_my_specific_type())
这会导致大量的数据库命中(每个通用记录一个,与容器相关),所以这显然不是这样做的方法。现在,也许可以通过直接获取 SpecificX 对象来完成:
s = Specific1.objects.filter(cont__name='somename')
# This gets me all Specific1 objects for the specified container
...
# do it for every Specific type
这样,对于每种特定类型,数据库都会被命中一次(我猜是可以接受的)。
我知道,.select_related() 不适用于 m2m 关系,所以在这里没有太大帮助。
重申一下,最终结果必须是一组 SpecificX 对象(不是 Generic)。
【问题讨论】:
-
回想起来,这个问题现在对我来说似乎有点毫无意义,因为我已经提供了唯一可能的答案。毕竟,没有办法从具有任意字段的多个表中获得联合结果集。好的,显然,这是一种方法,但它很丑陋并且涉及动态 sql 和/或“select *”。我想。
-
您的问题实际上与优化多对多关系无关,而与针对多表继承优化查询有关。这确实是一个难题。
-
现在我想起来了,是什么让我相信,这个问题是关于 m2m 关系的,实际上,select_related 并不遍历多对多关系。
标签: django orm django-models many-to-many django-queryset