diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-07-28 13:06:52 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-07-28 13:08:19 +0200 |
| commit | 247bcef6b4f8625e80b6f07e264b7bbdf330194d (patch) | |
| tree | 77f6aecfbafbf3d52ce84ca628d81581ddea62dd /tests/model_fields | |
| parent | 028a5f86f22d4be0746cbd38d09d6961024b2ef7 (diff) | |
[3.1.x] Fixed #31836 -- Dropped support for JSONField __contains and __contained_by lookups on SQLite.
The current implementation works only for basic examples without
supporting nested structures and doesn't follow "the general principle
that the contained object must match the containing object as to
structure and data contents, possibly after discarding some
non-matching array elements or object key/value pairs from the
containing object".
Backport of ba691933cee375195c9c50f333dd4b2a3abbb726 from master.
Diffstat (limited to 'tests/model_fields')
| -rw-r--r-- | tests/model_fields/test_jsonfield.py | 69 |
1 files changed, 36 insertions, 33 deletions
diff --git a/tests/model_fields/test_jsonfield.py b/tests/model_fields/test_jsonfield.py index 7b81f3f22c..a36b1fee21 100644 --- a/tests/model_fields/test_jsonfield.py +++ b/tests/model_fields/test_jsonfield.py @@ -1,6 +1,6 @@ import operator import uuid -from unittest import mock, skipIf, skipUnless +from unittest import mock, skipIf from django import forms from django.core import serializers @@ -426,17 +426,20 @@ class TestQuerying(TestCase): [self.objs[3], self.objs[4], self.objs[6]], ) - @skipIf( - connection.vendor == 'oracle', - "Oracle doesn't support contains lookup.", - ) + @skipUnlessDBFeature('supports_json_field_contains') def test_contains(self): tests = [ ({}, self.objs[2:5] + self.objs[6:8]), ({'baz': {'a': 'b', 'c': 'd'}}, [self.objs[7]]), + ({'baz': {'a': 'b'}}, [self.objs[7]]), + ({'baz': {'c': 'd'}}, [self.objs[7]]), ({'k': True, 'l': False}, [self.objs[6]]), ({'d': ['e', {'f': 'g'}]}, [self.objs[4]]), + ({'d': ['e']}, [self.objs[4]]), + ({'d': [{'f': 'g'}]}, [self.objs[4]]), ([1, [2]], [self.objs[5]]), + ([1], [self.objs[5]]), + ([[2]], [self.objs[5]]), ({'n': [None]}, [self.objs[4]]), ({'j': None}, [self.objs[4]]), ] @@ -445,38 +448,32 @@ class TestQuerying(TestCase): qs = NullableJSONModel.objects.filter(value__contains=value) self.assertSequenceEqual(qs, expected) - @skipUnless( - connection.vendor == 'oracle', - "Oracle doesn't support contains lookup.", - ) + @skipIfDBFeature('supports_json_field_contains') def test_contains_unsupported(self): - msg = 'contains lookup is not supported on Oracle.' + msg = 'contains lookup is not supported on this database backend.' with self.assertRaisesMessage(NotSupportedError, msg): NullableJSONModel.objects.filter( value__contains={'baz': {'a': 'b', 'c': 'd'}}, ).get() - @skipUnlessDBFeature('supports_primitives_in_json_field') + @skipUnlessDBFeature( + 'supports_primitives_in_json_field', + 'supports_json_field_contains', + ) def test_contains_primitives(self): for value in self.primitives: with self.subTest(value=value): qs = NullableJSONModel.objects.filter(value__contains=value) self.assertIs(qs.exists(), True) - @skipIf( - connection.vendor == 'oracle', - "Oracle doesn't support contained_by lookup.", - ) + @skipUnlessDBFeature('supports_json_field_contains') def test_contained_by(self): qs = NullableJSONModel.objects.filter(value__contained_by={'a': 'b', 'c': 14, 'h': True}) self.assertSequenceEqual(qs, self.objs[2:4]) - @skipUnless( - connection.vendor == 'oracle', - "Oracle doesn't support contained_by lookup.", - ) + @skipIfDBFeature('supports_json_field_contains') def test_contained_by_unsupported(self): - msg = 'contained_by lookup is not supported on Oracle.' + msg = 'contained_by lookup is not supported on this database backend.' with self.assertRaisesMessage(NotSupportedError, msg): NullableJSONModel.objects.filter(value__contained_by={'a': 'b'}).get() @@ -664,19 +661,25 @@ class TestQuerying(TestCase): ('value__baz__has_any_keys', ['a', 'x']), ('value__has_key', KeyTextTransform('foo', 'value')), ) - # contained_by and contains lookups are not supported on Oracle. - if connection.vendor != 'oracle': - tests += ( - ('value__contains', KeyTransform('bax', 'value')), - ('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) + + @skipUnlessDBFeature('supports_json_field_contains') + def test_contains_contained_by_with_key_transform(self): + tests = [ + ('value__contains', KeyTransform('bax', 'value')), + ('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( |
