首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >prefetch_related在GenericForeignKeys上的反向使用

prefetch_related在GenericForeignKeys上的反向使用
EN

Stack Overflow用户
提问于 2014-10-13 22:26:59
回答 1查看 631关注 0票数 2

我有动物和笼子。

代码语言:javascript
复制
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,这将是容易的。这句话应该是这样的:

代码语言:javascript
复制
Animal.objects.filter(content_type=ContentType.objects.get_for_model(Cage), object_id=16)

因此,我可以把动物关在每个笼子里,比如:

代码语言:javascript
复制
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向相反方向移动的情况下,我想不出任何方法来做到这一点。基本上,我想做的是:

代码语言:javascript
复制
cages = Cage.objects.prefetch_related('animal').all()

但在这种情况下,动物不是笼子对象的属性,笼子也不是动物物体的属性。两者之间的链接是动物模型中的内容类型和对象id,在某些情况下,它们表示一个笼。

任何关于如何做到这一点的想法都将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-08 12:10:54

如果凯奇有这样的东西:

代码语言:javascript
复制
animals = GenericRelation(Animal)

你可以去:

代码语言:javascript
复制
Cage.objects.filter(...).prefetch_related('animals').all()

(至少在Django 1.8.4.)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26349870

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档