Django filter-save QuerySet
<p>I've a django model:-</p>

<pre><code>class ModelA(models.Model):
    flag = models.BooleanField(default=True)
</code></pre>

<p>Next, I query it:- </p>

<p><code>obj = ModelA.objects.filter(flag=True)</code></p>

<p>Now, I change the <code>flag</code> of first object.</p>

<pre><code>obj1 = obj[0]
obj1.flag = False
obj1.save()
</code></pre>

<p>Now, when I get <code>obj[0]</code> again, it returns me the <code>2nd object</code> of the filtered query. <strong>Why?</strong></p>

<p>If you look at <code>Queryset.__getitem__()</code> (django/db/models/query.py), you'll find this (django 1.10):</p>

<pre><code>295  qs = self._clone()
296  qs.query.set_limits(k, k + 1)
297  return list(qs)[0]
</code></pre>

<p>Note that you only get there if the queryset has not been iterated yet - else it would fetch the instance from it's resultcache, and then you'd get the same instance twice.</p>

<p>FWIW, the point of this code is to optimize db access (by not fetching the whole dataset when a single instance is asked for), and yes this behaviour is quite suprising to say the least.</p>

<p>If what you want is to keep the modify the first item while still keeping it as part of the dataset AND you're going to use the whole dataset, the simplest solution is to make a <code>list</code> from your queryset before:</p>

<pre><code>obj = list(ModelA.objects.filter(flag=True))
obj1 = obj[0]
obj1.flag = False
obj1.save()
</code></pre>

python django django-queryset