Browse Source

Refs #31894 -- Added tests for JSONField key lookups with QuerySet.exclude().

jpribyl 4 years ago
parent
commit
94e2238107
1 changed files with 47 additions and 1 deletions
  1. 47 1
      tests/model_fields/test_jsonfield.py

+ 47 - 1
tests/model_fields/test_jsonfield.py

@@ -275,7 +275,7 @@ class TestQuerying(TestCase):
                 'n': [None],
             },
             [1, [2]],
-            {'k': True, 'l': False},
+            {'k': True, 'l': False, 'foo': 'bax'},
             {
                 'foo': 'bar',
                 'baz': {'a': 'b', 'c': 'd'},
@@ -616,6 +616,52 @@ class TestQuerying(TestCase):
         )
         self.assertIs(NullableJSONModel.objects.filter(value__c__lt=5).exists(), False)
 
+    def test_lookup_exclude(self):
+        tests = [
+            (Q(value__a='b'), [self.objs[0]]),
+            (Q(value__foo='bax'), [self.objs[0], self.objs[7]]),
+        ]
+        for condition, expected in tests:
+            self.assertSequenceEqual(
+                NullableJSONModel.objects.exclude(condition),
+                expected,
+            )
+            self.assertSequenceEqual(
+                NullableJSONModel.objects.filter(~condition),
+                expected,
+            )
+
+    def test_lookup_exclude_nonexistent_key(self):
+        # Values without the key are ignored.
+        condition = Q(value__foo='bax')
+        objs_with_value = [self.objs[6]]
+        objs_with_different_value = [self.objs[0], self.objs[7]]
+        self.assertSequenceEqual(
+            NullableJSONModel.objects.exclude(condition),
+            objs_with_different_value,
+        )
+        self.assertSequenceEqual(
+            NullableJSONModel.objects.exclude(~condition),
+            objs_with_value,
+        )
+        self.assertCountEqual(
+            NullableJSONModel.objects.filter(condition | ~condition),
+            objs_with_value + objs_with_different_value,
+        )
+        self.assertCountEqual(
+            NullableJSONModel.objects.exclude(condition & ~condition),
+            objs_with_value + objs_with_different_value,
+        )
+        # Add the __isnull lookup to get an exhaustive set.
+        self.assertSequenceEqual(
+            NullableJSONModel.objects.exclude(condition & Q(value__foo__isnull=False)),
+            self.objs[0:6] + self.objs[7:],
+        )
+        self.assertSequenceEqual(
+            NullableJSONModel.objects.filter(condition & Q(value__foo__isnull=False)),
+            objs_with_value,
+        )
+
     @skipIf(
         connection.vendor == 'oracle',
         'Raises ORA-00600: internal error code on Oracle 18.',