我有动物和笼子。
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models
class Cage(models.Model):
...
class Animal(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
...首先是模型笼子。目前,我正在尝试优化在遍历一个笼列表时所做的查询的数量。
那我们就有模型动物了。动物含有GenericForeignKey。动物所指的许多物体之一可以是笼子,但也可以是其他物体,比如食物。
如果我想要得到所有的动物对象,在笼子16,这将是容易的。这句话应该是这样的:
Animal.objects.filter(content_type=ContentType.objects.get_for_model(Cage), object_id=16)因此,我可以把动物关在每个笼子里,比如:
cage_content_type_id = ContentType.objects.get_for_model(Cage).id
animals_in_cage = {}
for cage in cages:
animals_in_cage[cage.id] = Animal.objects.filter(
content_type_id=cage_content_type_id,
object_id=cage.id
)这段代码的问题在于它将使O(n) SQL查询在其中n = len(cages)。理想情况下,我可以使用类似prefetch_related的东西提前在动物和笼子表上进行连接。但是,在GenericForeignKeys向相反方向移动的情况下,我想不出任何方法来做到这一点。基本上,我想做的是:
cages = Cage.objects.prefetch_related('animal').all()但在这种情况下,动物不是笼子对象的属性,笼子也不是动物物体的属性。两者之间的链接是动物模型中的内容类型和对象id,在某些情况下,它们表示一个笼。
任何关于如何做到这一点的想法都将不胜感激!
发布于 2015-12-08 12:10:54
如果凯奇有这样的东西:
animals = GenericRelation(Animal)你可以去:
Cage.objects.filter(...).prefetch_related('animals').all()(至少在Django 1.8.4.)
https://stackoverflow.com/questions/26349870
复制相似问题