django - 通过 Django ORM管理器( objects.all ( ) 返回的索引访问列表对象的问题

  显示原文与译文双语对照的内容
0 0

我有两个类,它们之间有one-to-many关系。

我在父对象('fm') 中运行了一个测试运行,它包含两个子对象,可以通过相关的manager ('。

以下代码运行,指示'变更日志'列表包含两个不同的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

地球上发生了什么?

[UPDATE yf_num_eayq8888_yf_num ]

在模型 _str_() 方法中添加了 ID,因此现在我可以看到索引方法的访问两次返回同一个记录:


>>> 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,没有什么花哨的。)

[UPDATE yf_num_eaza8888_yf_num ]

如果将 fm.changelog.all() 对象显式地发送到 list,测试将通过 @stevejalim, 调查:


>>> 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()]

基本上,这是一个神秘,但是转到列表是 job.1

时间: 原作者:

0 0

就像评论中所讨论的,解决这个问题的方法是将QuerySet作为列表返回。 我非常怀疑这是基础 Django 实现中的一个 Bug,因为在通过索引访问错误的元素时,我无法确定。

默认行为给出错误的( 意外) 结果:


>>> changelog = fm.changelog.all()
>>> changelog[0]
id:3 fred changed message status from Received to Read
>>> changelog[1]
id:3 fred changed message status from Received to Read

转换到列表给出了正确的( 应为) 结果:


>>> changelog = list(fm.changelog.all())
>>> changelog[0]
id:2 fred changed message status from New to Received
>>> changelog[1]
id:3 fred changed message status from Received to Read

原作者:
...