def test_nested_key_transform_raw_expression(self): expr = RawSQL(self.raw_sql, ['{"x": {"y": "bar"}}']) self.assertSequenceEqual( NullableJSONModel.objects.filter( value__foo=KeyTransform("y", KeyTransform("x", expr))), [self.objs[7]], )
def test_contains_contained_by_with_key_transform(self): tests = [ ("value__d__contains", "e"), ("value__d__contains", [{ "f": "g" }]), ("value__contains", KeyTransform("bax", "value")), ("value__baz__contains", { "a": "b" }), ("value__baz__contained_by", { "a": "b", "c": "d", "e": "f" }), ( "value__contained_by", KeyTransform( "x", RawSQL(self.raw_sql, ['{"x": {"a": "b", "c": 1, "d": "e"}}'])), ), ] # For databases where {'f': 'g'} (without surrounding []) matches [{'f': 'g'}]. if not connection.features.json_key_contains_list_matching_requires_list: tests.append(("value__d__contains", {"f": "g"})) for lookup, value in tests: with self.subTest(lookup=lookup, value=value): self.assertIs( NullableJSONModel.objects.filter(**{ lookup: value }).exists(), True)
def test_lookups_with_key_transform(self): tests = ( ("value__d__contains", "e"), ("value__baz__has_key", "c"), ("value__baz__has_keys", ["a", "c"]), ("value__baz__has_any_keys", ["a", "x"]), ("value__contains", KeyTransform("bax", "value")), ("value__has_key", KeyTextTransform("foo", "value")), ) # contained_by lookup is not supported on Oracle. if connection.vendor != "oracle": tests += ( ("value__baz__contained_by", { "a": "b", "c": "d", "e": "f" }), ( "value__contained_by", KeyTransform( "x", RawSQL(self.raw_sql, ['{"x": {"a": "b", "c": 1, "d": "e"}}']), ), ), ) for lookup, value in tests: with self.subTest(lookup=lookup): self.assertIs( NullableJSONModel.objects.filter(**{ lookup: value }).exists(), True)
def test_key_transform_expression(self): self.assertSequenceEqual( NullableJSONModel.objects.filter( value__d__0__isnull=False).annotate( key=KeyTransform("d", "value")).annotate( chain=KeyTransform("0", "key"), expr=KeyTransform("0", JSONCast("key", JSONField())), ).filter(chain=F("expr")), [self.objs[4]], )
def test_has_key_list(self): obj = NullableJSONModel.objects.create(value=[{"a": 1}, {"b": "x"}]) tests = [ Q(value__1__has_key="b"), Q(value__has_key=KeyTransform("b", KeyTransform(1, "value"))), Q(value__has_key=KeyTransform("b", KeyTransform("1", "value"))), ] for condition in tests: with self.subTest(condition=condition): self.assertSequenceEqual( NullableJSONModel.objects.filter(condition), [obj], )
def test_ordering_grouping_by_key_transform(self): base_qs = NullableJSONModel.objects.filter(value__d__0__isnull=False) for qs in ( base_qs.order_by("value__d__0"), base_qs.annotate(key=KeyTransform( "0", KeyTransform("d", "value"))).order_by("key"), ): self.assertSequenceEqual(qs, [self.objs[4]]) qs = NullableJSONModel.objects.filter(value__isnull=False) self.assertQuerysetEqual( qs.filter(value__isnull=False).annotate(key=KeyTextTransform( "f", KeyTransform("1", KeyTransform("d", "value")))).values( "key").annotate(count=Count("key")).order_by("count"), [(None, 0), ("g", 1)], operator.itemgetter("key", "count"), )
def test_has_key_deep(self): tests = [ (Q(value__baz__has_key="a"), self.objs[7]), (Q(value__has_key=KeyTransform("a", KeyTransform("baz", "value"))), self.objs[7]), (Q(value__has_key=KeyTransform("c", KeyTransform("baz", "value"))), self.objs[7]), (Q(value__d__1__has_key="f"), self.objs[4]), ( Q(value__has_key=KeyTransform( "f", KeyTransform("1", KeyTransform("d", "value")))), self.objs[4], ), ] for condition, expected in tests: with self.subTest(condition=condition): self.assertSequenceEqual( NullableJSONModel.objects.filter(condition), [expected], )