Django Models:通过外键保留对象身份 [英] Django Models: preserve object identity over foreign-key following

查看:255
本文介绍了Django Models:通过外键保留对象身份的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Django的ORM(版本1.2.3)不间断的保留身份。这最好用一个例子来解释:

  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



或者,您可以查看其中一个尝试修复此问题的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆