On 1/26/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: > > I'm not a fan of .all() either - if you can do .filter() on > Article.objects, then surely Article.objects is already a collection of > some kind. That's what is sounds like: Article.objects == all the > 'Article' objects.
And there's the original problem that started this mess ;-) Let me see if I can lay it all out. (Sorry to pick on your response Luke, not trying to single you out.) Case 1: Let's assume that MyModel.objects or my_object.related_set *IS* a Query object (in other words, it has state): MyModel.objects # returns Q1 MyModel.objects.filter(*args) # Q1 with filters applied q = MyModel.objects # q is Q1 q.filter(*args) # q is still Q1, but with filters now q.order_by('test') # q is still Q1 + filters + ordering q2 = MyModel.objects # oh shit, this is Q1 + filters + ordering, but I expected a new Q If you want to get 2 different iterators with different filter criteria, you need some sort of .clone() method on Query objects. q2 = MyModel.objects.clone() # ahhh... a new Q :) Case 2: Let's assume that MyModel.objects and my_object.related_set *RETURN* a *NEW* Query object. (In other words is stateless.) You might expect this: MyModel.objects # Q1 MyModel.objects.filter(*args) # Q1 with filters applied MyModel.objects.order_by(*args) # Q1 with ordering applied But in fact, you'll get this: MyModel.objects # Q1 MyModel.objects.filter(*args) # Q2 MyModel.objects.order_by(*args) # Q3 But this works fine: q = MyModel.objects # q is Q1 q.filter(*args) # q is Q1 with filters applied q.order_by(*args) # q is Q1 with ordering applied My point was that you have to explain the difference between the last two cases, or if MyModel.objects is stateful (as in Case 1) you need that clone method I talked about. (Also, non-intuitive) The syntax Robert proposed is very appealing to me, but AFAICS, the facts that follow from that syntax are confusing as hell. If I'm missing something, please let me know. > Also, if Query instances act as sets, they should support len(), and > you don't need .count() : Ian Bicking has kept len() out of SQLObject result sets even though it seems really intuitive to use. Here's a rundown of what I remember about his argument: __len__ would run "count (*)" against the db. I think iter() calls len() implicitly for performance reasons, so you'd be running a useless count(*) every time you started iterating over a Query object. On the other hand, maybe if the iterator has already cahced the objects, __len__ could just call len() on the cache. It might be possible to work something out. Joseph