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.