On Tue, 2008-08-26 at 08:05 -0700, [EMAIL PROTECTED] wrote:
> Hi guys,
> 
> I'm trying to optimize one of my views that is doing a rather (naive?)
> query like this:
> 
> ...
> post_stream = Post.objects.filter(poster=some_user)
> for other_user in other_user_queryset:
>     post_stream = post_stream | Post.objects.filter(poster=other_user)
> ...

[...]
> The ORM generates a SQL query for each of the additional piped OR
> queries (this becomes a large number very quickly!). 

Which version of Django are you using? Because this isn't true for the
current subversion code. How are you determining that a query is run
esach time?

Querysets are only evaluated when you first access their results and
"or"-ing together two querysets doesn't access the results, so it
constructs a single SQL query. The above loop should execute two
queries: one for the other_user_queryset (since you're accessing the
results there) and then one when you access the results of post_stream.

A more concise, and probably clearer, way to write the above loop is to
use Q() objects:

        post_filter = Q(poster=some_user)
        for user in other_queryset:
            post_filter = post_filter | Q(poster=user)
        post_stream = Post.objects.filter(post_filter)
        
That's a little bit more lightweight at the Python level, since it's not
constructing and copying a QuerySet object each time around. From a
style point of view it's also focusing on constructing the filter, which
is the significant thing the loop does, rather than the queryset, which
is just a way to get at the results which are filtered.

Regards,
Malcolm



--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to