ValuesQuerySet changes POST-qs-rf merge
Update: As Malcolm has commented below, the issue described here was in fact a bug which has now been fixed.
Just a quick note regarding of one area of change since the merge of the queryset-refactor branch into the trunk which has broken a specific use-case of the
To reduce the number of queries which are executed when accessing related items from a model I have one particular view which uses
values() to return
ValuesQuerySet representing the associated instance items. I then use a list comprehension to build a list of associated items and bind them to the parent object instance. This may sound bizzar, and if there’s another way which gives a ~3x reduction in the query count (from around 43 down to 15 in a specific case), I’m all ears - and no, using
select_related() would not help in this case. :)
This mocked-up sample code gives you an idea of what’s going on:
post_ids = [post.id for post in posts] message_items = Messages.objects.filter(post__in=post_ids).values() for post in posts: post.message_items = [message for message in message_items if message['post_id'] == post.id]
However, since the merge,
message_items will be re-evaluated (causing the query to be re-executed) for each iteration of the list comprehension.
The fix: simply cast the
ValuesQuerySet returned by
values() to a standard list.
messages_items = list(Messages.objects.filter(post__in=post_ids).values())
Note of caution: You probably wouldn’t want to do this if your objects are potentially large (they contain a large amount of text) or you’re returning a lot at once as it will eat up memory.