>>> type(Person.objects.all())
<class 'django.db.models.query.QuerySet'>
>>> pa = Person.objects.all() # Not evaluated yet - lazy
>>> type(pa)
<class 'django.db.models.query.QuerySet'>
DB queried to give you a Person object
>>> pa[2]
DB queried again to give you yet another Person object.
>>> pa[2].first_name = "Blah"
Let's call this instance PersonObject1 that resides in memory. So it's equivalent to something like this:
>>> PersonObject1.first_name = "Blah"
Now let's do this:
>>> pa[2].save()
The pa[2] again queries a db an returns Another instance of person object, say PersonObject2 for example. Which will be unchanged! So it's equvivalent to calling something like:
PersonObject2.save()
But this has nothing to do with PersonObject1.