On Tue, Dec 8, 2009 at 8:22 PM, Luke Plant <l.plant...@cantab.net> wrote:
> Hi all,
>
> I discovered that QuerySet supports the 'in' operator:
>
>  myset = Articles.objects.filter(foo=bar)
>  if someobject in myset:
>      # etc.
>
> The Python docs I could find imply (but don't state) that if there is
> no __contains__() method, but there is __getitem__(), then
> __getitem__() is called repeatedly, starting with zero, until
> IndexError, and it then does an 'in' on the resulting list.
>
> That would be very inefficient with a QuerySet, but thankfully it
> appears from stepping through a debugger that that doesn't happen if
> you define __iter__() (as we have on QuerySet) - it actually calls
> __iter__() until StopIteration, and does 'in' on that list.
>
> This means that the above code is pretty efficient - it does just one
> SQL query.
>
> However, it could be slightly more efficient in some cases, because
> the entire QuerySet._result_cache does not necessarily need to be
> filled - we can stop if we find a match, saving us the work of
> building Model objects that might not be needed.
>
> The plumbing to do this is all there already - we already optimize the
> __nonzero__ method in this way, by getting just the first result. It
> can of course be continued if the rest of the set is needed.
>
> So, I'm thinking of implementing the __contains__ method to do this
> optimization.  Can anyone think of reasons why not?  I think the 'in'
> operator is perfectly well defined for QuerySets.
>
> I don't see this as something that should be documented as a normal
> way to do membership tests, as there will often be much more efficient
> ways to do it using ORM methods.  But, it is something that developers
> might do, and with the addition of the 'in' operator in the 'if' tag,
> it's something that template authors will be able to do.
>
> An explicit __contains__ method also protects us against changes in
> Python which could produce quite different performance.
>
> Regards,
>
> Luke
>
> --
> "If something is hard, it's not worth doing." (Homer Simpson)
>
> Luke Plant || http://lukeplant.me.uk/
>
> --
>
> You received this message because you are subscribed to the Google Groups 
> "Django developers" group.
> To post to this group, send email to django-develop...@googlegroups.com.
> To unsubscribe from this group, send email to 
> django-developers+unsubscr...@googlegroups.com.
> For more options, visit this group at 
> http://groups.google.com/group/django-developers?hl=en.
>
>
>

Sounds like a reasonable optimization, to do, and I can't think of any
reasons not to.

Alex

-- 
"I disapprove of what you say, but I will defend to the death your
right to say it." -- Voltaire
"The people's good is the highest law." -- Cicero
"Code can always be simpler than you think, but never as simple as you
want" -- Me

--

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


Reply via email to