mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Fixed #31829 -- Used JSONField __contains lookup on key transforms.
This commit is contained in:
		| @@ -431,10 +431,6 @@ class KeyTransformIContains(CaseInsensitiveMixin, KeyTransformTextLookupMixin, l | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class KeyTransformContains(KeyTransformTextLookupMixin, lookups.Contains): | ||||
|     pass | ||||
|  | ||||
|  | ||||
| class KeyTransformStartsWith(KeyTransformTextLookupMixin, lookups.StartsWith): | ||||
|     pass | ||||
|  | ||||
| @@ -486,7 +482,6 @@ class KeyTransformGte(KeyTransformNumericLookupMixin, lookups.GreaterThanOrEqual | ||||
| KeyTransform.register_lookup(KeyTransformExact) | ||||
| KeyTransform.register_lookup(KeyTransformIExact) | ||||
| KeyTransform.register_lookup(KeyTransformIsNull) | ||||
| KeyTransform.register_lookup(KeyTransformContains) | ||||
| KeyTransform.register_lookup(KeyTransformIContains) | ||||
| KeyTransform.register_lookup(KeyTransformStartsWith) | ||||
| KeyTransform.register_lookup(KeyTransformIStartsWith) | ||||
|   | ||||
| @@ -905,10 +905,10 @@ To query for missing keys, use the ``isnull`` lookup:: | ||||
|  | ||||
|     The lookup examples given above implicitly use the :lookup:`exact` lookup. | ||||
|     Key, index, and path transforms can also be chained with: | ||||
|     :lookup:`contains`, :lookup:`icontains`, :lookup:`endswith`, | ||||
|     :lookup:`iendswith`, :lookup:`iexact`, :lookup:`regex`, :lookup:`iregex`, | ||||
|     :lookup:`startswith`, :lookup:`istartswith`, :lookup:`lt`, :lookup:`lte`, | ||||
|     :lookup:`gt`, and :lookup:`gte` lookups. | ||||
|     :lookup:`icontains`, :lookup:`endswith`, :lookup:`iendswith`, | ||||
|     :lookup:`iexact`, :lookup:`regex`, :lookup:`iregex`, :lookup:`startswith`, | ||||
|     :lookup:`istartswith`, :lookup:`lt`, :lookup:`lte`, :lookup:`gt`, and | ||||
|     :lookup:`gte`, as well as with :ref:`containment-and-key-lookups`. | ||||
|  | ||||
| .. warning:: | ||||
|  | ||||
| @@ -937,8 +937,10 @@ To query for missing keys, use the ``isnull`` lookup:: | ||||
|     On PostgreSQL, if only one key or index is used, the SQL operator ``->`` is | ||||
|     used. If multiple operators are used then the ``#>`` operator is used. | ||||
|  | ||||
| Containment and key operations | ||||
| ------------------------------ | ||||
| .. _containment-and-key-lookups: | ||||
|  | ||||
| Containment and key lookups | ||||
| --------------------------- | ||||
|  | ||||
| .. fieldlookup:: jsonfield.contains | ||||
|  | ||||
|   | ||||
| @@ -608,12 +608,29 @@ class TestQuerying(TestCase): | ||||
|             self.objs[3:5], | ||||
|         ) | ||||
|  | ||||
|     @skipUnlessDBFeature('supports_json_field_contains') | ||||
|     def test_array_key_contains(self): | ||||
|         tests = [ | ||||
|             ([], [self.objs[7]]), | ||||
|             ('bar', [self.objs[7]]), | ||||
|             (['bar'], [self.objs[7]]), | ||||
|             ('ar', []), | ||||
|         ] | ||||
|         for value, expected in tests: | ||||
|             with self.subTest(value=value): | ||||
|                 self.assertSequenceEqual( | ||||
|                     NullableJSONModel.objects.filter(value__bar__contains=value), | ||||
|                     expected, | ||||
|                 ) | ||||
|  | ||||
|     def test_key_iexact(self): | ||||
|         self.assertIs(NullableJSONModel.objects.filter(value__foo__iexact='BaR').exists(), True) | ||||
|         self.assertIs(NullableJSONModel.objects.filter(value__foo__iexact='"BaR"').exists(), False) | ||||
|  | ||||
|     @skipUnlessDBFeature('supports_json_field_contains') | ||||
|     def test_key_contains(self): | ||||
|         self.assertIs(NullableJSONModel.objects.filter(value__foo__contains='ar').exists(), True) | ||||
|         self.assertIs(NullableJSONModel.objects.filter(value__foo__contains='ar').exists(), False) | ||||
|         self.assertIs(NullableJSONModel.objects.filter(value__foo__contains='bar').exists(), True) | ||||
|  | ||||
|     def test_key_icontains(self): | ||||
|         self.assertIs(NullableJSONModel.objects.filter(value__foo__icontains='Ar').exists(), True) | ||||
| @@ -670,7 +687,6 @@ class TestQuerying(TestCase): | ||||
|  | ||||
|     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']), | ||||
| @@ -685,7 +701,10 @@ class TestQuerying(TestCase): | ||||
|     @skipUnlessDBFeature('supports_json_field_contains') | ||||
|     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', | ||||
| @@ -695,8 +714,11 @@ class TestQuerying(TestCase): | ||||
|                 )), | ||||
|             ), | ||||
|         ] | ||||
|         # PostgreSQL requires a layer of nesting. | ||||
|         if connection.vendor != 'postgresql': | ||||
|             tests.append(('value__d__contains', {'f': 'g'})) | ||||
|         for lookup, value in tests: | ||||
|             with self.subTest(lookup=lookup): | ||||
|             with self.subTest(lookup=lookup, value=value): | ||||
|                 self.assertIs(NullableJSONModel.objects.filter( | ||||
|                     **{lookup: value}, | ||||
|                 ).exists(), True) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user