diff --git a/tests/test_queryset.py b/tests/test_queryset.py index 513979035..1f564ee4c 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -129,6 +129,20 @@ def test_slicing_negative_values(db): _ = IntFields.all()[:-1] +def test_integer_indexing_not_supported(db): + with pytest.raises( + ParamsError, + match=( + r"QuerySet indices must be slices, not integers\. " + r"QuerySets are lazy and do not support random access\. " + r"Use await queryset\.first\(\), await queryset\.offset\(n\)\.first\(\), " + r"or await queryset\.all\(\) and index the returned list\." + ), + ): + # Use an index way outside reasonable bounds for the dataset, so we don't accidentally support it. + _ = IntFields.all()[1000] + + def test_slicing_stop_before_start(db): with pytest.raises( ParamsError, diff --git a/tortoise/queryset.py b/tortoise/queryset.py index 0cfd2fc52..5da6ef9f7 100644 --- a/tortoise/queryset.py +++ b/tortoise/queryset.py @@ -554,6 +554,13 @@ def __getitem__(self, key: slice) -> QuerySet[MODEL]: or None. """ if not isinstance(key, slice): + if isinstance(key, int): + raise ParamsError( + "QuerySet indices must be slices, not integers. " + "QuerySets are lazy and do not support random access. " + "Use await queryset.first(), await queryset.offset(n).first(), " + "or await queryset.all() and index the returned list." + ) raise ParamsError("QuerySet indices must be slices.") if not (key.step is None or (isinstance(key.step, int) and key.step == 1)):