我有两个类,它们之间是一对多的关系。
我有一个测试运行,导致父对象('fm')包含两个子对象,可通过相关管理器('changelog')访问。
以下代码运行,表明“更改日志”列表包含两个不同的UserMessageStatusUpdate
对象,具有不同的属性:
>>> logging.debug(fm.changelog.all())
DEBUG [<UserMessageStatusUpdate: fred changed message status from New to Received>,
<UserMessageStatusUpdate: fred changed message status from Received to Read>]
我也可以遍历它们:
>>> for m in fm.changelog.all():
....logging.debug(m)
DEBUG fred changed message status from New to Received
DEBUG fred changed message status from Received to Read
但是,如果我尝试通过索引访问每个对象,我会得到完全不同的东西:
>>> logging.debug(fm.changelog.all()[0])
DEBUG fred changed message status from Received to Read
>>> logging.debug(fm.changelog.all()[1])
DEBUG fred changed message status from Received to Read
这到底是怎么回事?
[更新 1]
我已将 ID 添加到模型 _str_() 方法中,所以现在我可以看到按索引访问方法两次返回相同的记录:
>>> logging.debug(fm.changelog.all()[0])
DEBUG id:3 fred changed message status from Received to Read
>>> logging.debug(fm.changelog.all()[1])
DEBUG id:3 fred changed message status from Received to Read
那么现在的问题是,为什么经理在通过索引访问时返回相同的记录?(这是默认的Manager
,没什么特别的。)
[更新 2]
使用@stevejalim 对此进行调查,如果fm.changelog.all()
对象显式地大小写为 a ,则测试将通过list
:
>>> changelog = list(fm.changelog.all())
>>> logging.debug(changelog[0])
DEBUG id:2 fred changed message status from New to Received
>>> logging.debug(changelog[1])
DEBUG id:3 fred changed message status from Received to Read
查看 fm.changelog.all():
>>> logging.debug(type(fm.changelog.all()))
DEBUG <class 'django.db.models.query.QuerySet'>
似乎问题可能与返回生成器的查询集有关,并且无法通过索引直接访问项目。或者可能与RelatedManager
课堂上的这一行有关:https ://github.com/django/django/blob/stable/1.4.x/django/db/models/fields/related.py#L458
def get_query_set(self):
try:
return self.instance._prefetched_objects_cache[rel_field.related_query_name()]
基本上,这是一个谜,但投射到列表中就可以了。 1