﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
22503	Inconsistent behavior when a QuerySet is sliced	Luis A. Arce	nobody	"I think that the current behavior of the QuerySet.slice method is not consistent. Just an example:

{{{

def limited_filtering(max_results=10, *args, **kwargs){
    """"""
    Returns a Queryset
    """"""

    returns SomeModel.filter(*args, **kwargs)[:max_results]
}

# ...

def other_method_somewhere(queryset){
    """"""
    Expects a Queryset of SomeModel and returns the same Queryset filtered again
    """"""

    return queryset.filter(some_other_criteria)
}

other_method_somewhere(limited_filtering(*args, **kwargs)); # raises ""AssertionError: Cannot filter a query once a slice has been taken.""
}}}

Given the previous code, it is legit and fair that `other_method_somewhere` expects, as in most situations, a filtrable `QuerySet`. Not allowing a sliced `QuerySet` to be filtered after being sliced adds an edge case difficult to handle when methods using a `QuerySet` type are somehow semantically far away from each other (and thus, they don't know if the other is returning an sliced QuerySet).

Without knowing the exact reasons why this was implemented this way, the possible solutions I can come with are:

 * The most natural one, to make the sliced `QuerySet`s filtrable.
 * To make all the returned query sets in which `can_filter == False` to return a new type of `QuerySet`, something like `InmutableQuerySet` in order to take advantage of other methods related to them (`values_list`, etc.).
 * To make `QuerySet`'s slices return list or other type of collection (I guess this is impossible without breaking backwards compatibility).

Actually, the last case is supposedly the way one would expect it to work according to the documentation:


https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated
  > '''Slicing'''. As explained in Limiting QuerySets, a QuerySet can be sliced, using Python’s array-slicing syntax. Slicing an unevaluated QuerySet usually returns another unevaluated QuerySet, but Django will execute the database query if you use the “step” parameter of slice syntax, and will return a list. Slicing a QuerySet that has been evaluated (partially or fully) also returns a list.

By the way, there is also no reference in the documentation(or at least I could not find it) to the public method `QuerySet.can_filter`."	New feature	closed	Database layer (models, ORM)	1.6	Normal	fixed	QuerySet, filter, slice	Дилян Палаузов	Accepted	0	0	0	0	0	0
