我知道django querysey是一个生成器而不是列表。
my_items = Item.objects.filter(id = 1)
my_items[0].name = 'joe'
my_items[0].save()
在示例中,my_items [0]是对象的副本,因此保存不会修改对象 虽然这会起作用(不会创建副本)
my_items = Item.objects.filter(id = 1)
my_item = my_items[0]
my_item.name = 'joe'
my_item.save()
在django docs(或其他任何地方)中解释这种行为的地方? 为什么他们选择返回对象的副本而不是对象本身?
答案 0 :(得分:4)
记录在the section about querysets and caching中。它不仅仅是现有对象的副本。每次执行此操作时,Django都会对数据库进行单独查询,并根据响应创建新对象。以下是文档提供的示例:
>>> queryset = Entry.objects.all()
>>> print queryset[5] # Queries the database
>>> print queryset[5] # Queries the database again
但是,如果已经评估了您的查询集,则使用索引运算符获取对象将不会访问数据库,并且每次都会获得相同的对象(如文档中所示)。
更新:我被要求进一步澄清,所以这里有:
您认为您正在获取该对象的副本,但这并非严格正确。您将获得两个不同的Python对象,这些对象是独立创建的,但基于相同的数据库条目。那是因为每次使用索引操作符时都会查询数据库并创建一个新对象(前提是查询未经过评估)。
在您的情况下,您使用操作符两次,两次都命中数据库。第一次是在第二行:my_items[0].name = 'joe'
;第二次在第三行:my_items[0].save()
。每次执行my_items[0]
时,您都在使用运算符,查询数据库并创建新对象。因此,您将保存与修改后不同的对象。
答案 1 :(得分:0)
你在第二行写“my_itMes”的事实是否重要?
Item.objects.filter(pk = 1).update(name = 'Joe')
OR
myitem = Item.objects.get(id=1)
myitem.name = 'joe'
myitem.save()
您要求的文件:
https://docs.djangoproject.com/en/1.5/topics/db/queries/#filtered-querysets-are-unique
每次优化QuerySet时,都会得到一个全新的QuerySet,它不会绑定到之前的QuerySet。每个细化都会创建一个独立且独特的QuerySet,可以存储,使用和重用。