我想知道如何确保循环中每个循环中查询集循环中的所有模型实例都是最新的。
在我有一个带有name属性的模型并且我更新循环中的name属性的情况下,查询集不会获取循环本身所做的更改。查询集可能在循环开始时被缓存,并且在循环期间不会更新。
如何更新主循环查询集,以便在下面的示例中获得所需的结果?
的myapp / models.py
class mymodel(models.Model):
name = models.TextField()
在shell中循环
from myapp.models import mymodel
mymodel.objects.create(name='A')
mymodel.objects.create(name='BAB')
mymodel.objects.create(name='CBB')
for mod1 in mymodel.objects.all():
# Loop over all mod2
for mod2 in mymodel.objects.filter(name__contains=mod1.name).exclude(id=mod1.id):
# Remove mod1.name from mod2.name
mod2.name = ''.join(mod2.name.split(mod1.name))
# Save mod2
mod2.save()
[mod1.name for mod1 in mymodel.objects.all()]
结果
[u'A', u'BB', u'CBB']
期望的结果(第二个项目在第一次循环迭代后变为BB,这可以在迭代的第二步中从CBB中过滤出来,借给C)。
Out: [u'A', u'BB', u'C']
我尝试使用iterator()
作为查询集,但这并没有改变结果。
答案 0 :(得分:2)
你的代码不起作用的原因是因为外部循环中的查询在开始时执行了一次,但是每个对象都可以在内部循环中更新,这会导致它们过时。
例如,在创建所有对象后,您有[“A”,“BAB”,“CBB”]。当mod1
为“A”时,它将“BAB”更改为“BB”,但外部循环中的第二个对象已经加载,因此当外部循环的第二次迭代发生时,它会查询数据库{ {1}}而不是name__contains="BAB"
,正如您所期望的那样。
您可以通过改变内存中的所有对象来解决此问题(假设您的表足够小):
name__contains"BB"