1👍
The issue you’re seeing is likely due to the fact that Django QuerySet values_lists return generators. Since 1.9, QuerySet.values_list
implements an iterable class like FlatValuesListIterable Prior to 1.9, QuerySet.values_list
returned an instance of ValuesListQuerySet… Both of these return a generator, so the query is executed each time you access the variable (hence the behavior you were seeing when calling print).
The resulting object will behave a lot like a list, which is confusing, but if you need proof it’s not a list, try this:
from_values_ids = TestObject.objects.filter(value=value_1).values_list('id', flat=True)
from_list_ids = [obj.id for obj in TestObject.objects.filter(value=value_1)]
combined_list = from_values_ids + from_list_ids
… this will result in:
TypeError: unsupported operand type(s) for +: 'ValuesListQuerySet' and 'list'
The solution is simply to cast your from_values_ids
variable as a list:
from_values_ids = list(TestObject.objects.filter(value=value_1).values_list('id', flat=True))
or just generate the list yourself:
from_values_ids = [obj.id for obj in TestObject.objects.filter(value=value_1)]
1👍
Your understanding is correct. Django querysets are lazy.
from_values_ids = TestObject.objects.filter(value=value_1).values_list('id', flat=True) # doesn't hit the db
to_values_ids = TestObject.objects.filter(value=value_2).values_list('id', flat=True) # doesn't hit the db
Now when you do:
TestObject.objects.filter(id__in=from_values_ids).update(value=value_2)
|
|__> will fetch from db
Now all the values that matched value_1
got updated to value_2
. Now next line is executed:
TestObject.objects.filter(id__in=to_values_ids).update(value=value_1)
|
|__> Will actually execute the query you assigned it
# TestObject.objects.filter(value=value_2).values_list('id', flat=True)
At this moment all the objects that match value_2
are fetched and updated to value_1
But you see no difference because you have all value_1
in the database before starting. Hence from_values_ids
fetches all the objects and updates them to value_2
and then back to value_1
. See having a mix of value_1
and value_2
records in the database. The difference will be evident.
- [Answered ]-Django downloading a csv file with variable in name
- [Answered ]-Django: TypeError: context must be a dict rather than str
- [Answered ]-Django – how to query user profile based on User model having OneToOneField