Array slicing doesn't always return a QuerySet and shouldn't be adapted to
this proposed behavior. Directly exposing Query.set_limits() on the
QuerySet would most likely have confusing behavior to at least some group
of people.

Given the current behavior of Query.set_limits(), what should be the slice
start/stop for the below?

UTPerson.objects.all().set_limits(low=1,
high=10).filter(...).set_limits(low=1, high=10)

If you guessed, low=1 and high=10, you'd be wrong. Subsequent calls to
set_limits() "are applied relative to the existing constraints." That
behavior can be changed by having the QuerySet.set_limits() call
Query.clear_limits() before Query.set_limits(), but that would probably be
confusing to those that are familiar with how Query.set_limits() behaves.

If you want to be able to further filter and reapply/change the limits, you
can do that already. You can't do it as chained QuerySet calls, but the
only time this would make sense in code is when a QuerySet was passed with
a potentially unknown can_filter state, so you'd need to reset it before
using it.

if not qs.query.can_filter():
    qs.query.clear_limits()
qs.filter(...)[:10]

Regards,
Michael Manfre



On Mon, Sep 30, 2013 at 9:41 AM, Rimvydas Naktinis <[email protected]>wrote:

> I completely agree with Gary's argumentation here. And I would love to see
> .limit() introduced (or array slicing adapted).
>
> I ran into a situation where I have access into intermediate queryset()
> construction, where I normally do add .filter() statements, but now I had
> to limit a number of queries returned and it caused an exception, because
> some other code further down the stack was modifying.
>
> The actual query construction should be the final step, and in that case
> it doesn't matter when and how many times an equivalent of .limit() (or for
> that matter slicing) was called on the queryset. Just use the final one.
>
> On Wednesday, December 5, 2007 5:14:55 AM UTC, Gary Wilson wrote:
>>
>> Luke Plant wrote:
>> > On Tuesday 04 December 2007 07:25:31 Gary Wilson wrote:
>> >
>> >> Sort of my point.  Since filter() and [:] both return QuerySets why
>> >> should they be any different:
>> >>
>> >> UTPerson.objects.all().filter(**name__startswith='a')[:10]
>> >
>> > 1) This, logically, should return the first ten people whose 'name'
>> > starts with 'a'.
>> >
>> >> UTPerson.objects.all()[:10].**filter(name__startswith='a')
>> >
>> > 2) This should return the people whose 'name' starts with 'a' from the
>> > first 10 rows in the table
>> >
>> > This is almost certainly what most people would expect (I guess we
>> could
>> > argue about that...)  But there is no way to specify it in SQL without
>> > doing subselects -- you will end up doing 1) instead.
>>
>> Does that mean that most people also expect:
>>
>> UTPerson.objects.filter(first_**name__startswith='a').filter(**
>> last_name__startswith='b')
>>
>> to return the people whose last name starts with 'b' from the people whose
>> first name starts with 'a'?  Maybe, but filter doesn't work that way just
>> like
>> slicing wouldn't work that way.
>>
>> I should be able to keep piling things onto the QuerySet.  You can do it
>> with
>> all the other QuerySet methods that return QuerySets.  Why not with the
>> slicing syntax (which returns a QuerySet object)?
>>
>> I am just trying to spark some discussion on the matter.  Personally, I
>> wouldn't mind if slices were changed to always return lists (like the do
>> currently if you use a step).  And then we and in a limit() method for
>> people
>> who want QuerySets returned so that they can be built up and lazily
>> evaluated.
>>
>> I see:
>>
>> UTPerson.objects.all().limit(**10).filter(...).limit(10)
>>
>> acting like order_by() in that the second limit would override the first.
>>
>> > Remember that there are other methods that do not or cannot commute
>> e.g.
>> > trying to do order_by() after slicing -- it would change the objects
>> > that are returned.  Just because some methods do happen to commute
>> > (filtering) doesn't mean that others should.
>>
>> Well, with order_by() you can do:
>>
>> UTPerson.objects.all().order_**by('first_name').filter(...).**
>> order_by('last_name')
>>
>> In this case, the second order_by() overrides the first.
>>
>> Gary
>>
>>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/be64f70b-4443-4c76-9ff5-db3f35fdef14%40googlegroups.com
> .
> For more options, visit https://groups.google.com/groups/opt_out.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAGdCwBvvGFmcRNKU0izLwOvJBErq6-RF0wwzHvoAxNMNfDH-Nw%40mail.gmail.com.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to