Fixed #29049 -- Added slicing notation to F expressions.

Co-authored-by: Priyansh Saxena <askpriyansh@gmail.com>
Co-authored-by: Niclas Olofsson <n@niclasolofsson.se>
Co-authored-by: David Smith <smithdc@gmail.com>
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Co-authored-by: Abhinav Yadav <abhinav.sny.2002@gmail.com>
This commit is contained in:
Nick Pope 2023-12-30 07:24:30 +00:00 committed by GitHub
parent 561e16d6a7
commit 94b6f101f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 256 additions and 4 deletions

View file

@ -10,7 +10,7 @@ from django.core import checks, exceptions, serializers, validators
from django.core.exceptions import FieldError
from django.core.management import call_command
from django.db import IntegrityError, connection, models
from django.db.models.expressions import Exists, OuterRef, RawSQL, Value
from django.db.models.expressions import Exists, F, OuterRef, RawSQL, Value
from django.db.models.functions import Cast, JSONObject, Upper
from django.test import TransactionTestCase, override_settings, skipUnlessDBFeature
from django.test.utils import isolate_apps
@ -594,6 +594,40 @@ class TestQuerying(PostgreSQLTestCase):
[None, [1], [2], [2, 3], [20, 30]],
)
def test_slicing_of_f_expressions(self):
tests = [
(F("field")[:2], [1, 2]),
(F("field")[2:], [3, 4]),
(F("field")[1:3], [2, 3]),
(F("field")[3], [4]),
(F("field")[:3][1:], [2, 3]), # Nested slicing.
(F("field")[:3][1], [2]), # Slice then index.
]
for expression, expected in tests:
with self.subTest(expression=expression, expected=expected):
instance = IntegerArrayModel.objects.create(field=[1, 2, 3, 4])
instance.field = expression
instance.save()
instance.refresh_from_db()
self.assertEqual(instance.field, expected)
def test_slicing_of_f_expressions_with_annotate(self):
IntegerArrayModel.objects.create(field=[1, 2, 3])
annotated = IntegerArrayModel.objects.annotate(
first_two=F("field")[:2],
after_two=F("field")[2:],
random_two=F("field")[1:3],
).get()
self.assertEqual(annotated.first_two, [1, 2])
self.assertEqual(annotated.after_two, [3])
self.assertEqual(annotated.random_two, [2, 3])
def test_slicing_of_f_expressions_with_len(self):
queryset = NullableIntegerArrayModel.objects.annotate(
subarray=F("field")[:1]
).filter(field__len=F("subarray__len"))
self.assertSequenceEqual(queryset, self.objs[:2])
def test_usage_in_subquery(self):
self.assertSequenceEqual(
NullableIntegerArrayModel.objects.filter(