Django Models:通过外键保留对象身份 [英] Django Models: preserve object identity over foreign-key following
问题描述
class Parent(models.Model):
pass
class Child(models.Model):
parent = models.ForeignKey(Parent)
parent = Parents.objects.get(id = 1)
parent.child_set.all():
print id(child.parent),=!,id(parent)
所以,对于每个孩子,父母都会从数据库中重新获取,即使我们知道父母在我们抓取孩子的时候。这是对我的违反直觉。
在我的情况下,这也导致性能问题,因为我在父级进行一些繁重的操作,我想缓存在对象实例级别。然而,由于这些计算的结果是通过child => parent链接访问的,因此父级级别的缓存是无用的。
有关如何解决这个问题的任何想法?
我已经知道有一个ForeignRelatedObjectsDescriptor和一个ReverseSingleRelatedObjectDescriptor。
有一些可能的解决方案。
也许最简单的就是自己跟踪父母:
parent = Parents.objects.get(id = 1)
为parent.child_set.all()中的子代:
子项。 _parent_cache = parent
_FOO_cache
是Django的方式跟踪通过ForeignKey获取的项目,所以如果您使用已有的父项预先填充该孩子的对象,那么当您引用 child.parent $ c $时,Django将无法再次获取该对象c>。
或者,您可以查看其中一个尝试修复此问题的d方库 - django-idmapper 或 django-selectreverse 是我知道的两个。
Django's ORM (version 1.2.3) does not preserve identity when following foreign keys back and forth. This is best explained with an example:
class Parent(models.Model):
pass
class Child(models.Model):
parent = models.ForeignKey(Parent)
parent = Parents.objects.get(id=1)
for child in parent.child_set.all():
print id(child.parent), "=!", id(parent)
So, for each child the parent is re-fetched from the database, even though we know the parent at the moment we fetch the child. This is counterintuitive to me.
In my case this also leads to performance issues, since I do some heavy operations at the parent level which I'd like to cache at object instance level. However, since the results of these calculations are accessed via the child => parent link, this caching at the parent level is useless.
Any ideas on how to solve this?
I've gotten as far as figuring out there's a ForeignRelatedObjectsDescriptor and a ReverseSingleRelatedObjectDescriptor.
There are a number of possible solutions to this.
Perhaps the easiest is to keep track of the parent yourself:
parent = Parents.objects.get(id=1)
for child in parent.child_set.all():
child._parent_cache = parent
_FOO_cache
is the way Django keeps track of items fetched via ForeignKey, so if you pre-populate that object on the child with the parent you already have, Django won't fetch it again when you reference child.parent
.
Alternatively, you could look into one of the third-party libraries that attempt to fix this - django-idmapper or django-selectreverse are two I know of.
这篇关于Django Models:通过外键保留对象身份的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!