为什么Django模型字段在遍历关系时会不同步?

时间:2011-04-25 23:16:56

标签: django orm django-models

我遇到了访问已更改模型字段的问题,在Django 1.3应用程序中遍历关系。内存中的对象不会反映提交到数据库的更改。我正在使用Auth Middleware中的User()对象,将其链接到自定义的Profile()对象:

User() <---one-to-one---> Profile()

访问User()的email字段时出现问题:

$ python manage.py shell
>>> from django.contrib.auth.models import User
>>> from myproject.myapp.models import Profile
>>>
>>> user = User.objects.get(pk=1)
>>> profile = user.profile
>>> user.email
u'old@example.com'                  # OK.
>>> profile.user.email
u'old@example.com'                  # OK.
>>> 
>>> user.email = 'new@example.com'  # 1) Changes email address.
>>> user.save()                     # 2) Commits to database.
>>> user.email
'new@example.com'                   # 3) Changes reflected in user.email. Good.
>>> profile.user.email
u'old@example.com'                  # 4) Wrong. This is the old incorrect email.
>>> user.profile.user.email
u'old@example.com'                  # 5) Also wrong.
>>> 
>>> profile = Profile.objects.get(user=user)
>>> profile.user.email
u'new@example.com'                  # 6) If we re-query the DB, things are OK.

为什么第4步和第5步中的事情不同步?我被#5困惑,从保存的用户对象转到配置文件,然后回到同一个保存的用户对象。

显然存在某种缓存,但我不确定它背后的逻辑/算法。任何人都知道发生了什么,以及在代码中处理此问题的最佳方法?感谢您提供的任何见解! :)

2 个答案:

答案 0 :(得分:2)

负责透明查找相关对象的SingleRelatedObjectDescriptor描述符检查Model实例中_<fieldname>_cache中相关对象的缓存版本,并在第一次检索时对其进行缓存。

Django的ORM不使用身份映射,因此对一个Model实例的更改不会自动反映在现有引用所持有的其他实例中。

答案 1 :(得分:1)

profile.user user。您正在查看的是Django的ORM之前从数据库中提取的模型的另一个缓存副本。如果您绝对必须拥有最新值,则每次都需要重新查询。