summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDmitry Dygalo <dadygalo@gmail.com>2018-02-20 16:47:12 +0100
committerTim Graham <timograham@gmail.com>2018-04-04 10:53:46 -0400
commitc979c0a2b8abca325a549961fd7a17bdc36bcb1f (patch)
treeb6d221918b9c0989cbb3d6dc08cd7ebee08381bf /tests
parent4fe5d846666d46a5395a5f0ea2845a96b6837a75 (diff)
Fixed #25718 -- Made a JSONField lookup value of None match keys that have a null value.
Diffstat (limited to 'tests')
-rw-r--r--tests/lookup/models.py7
-rw-r--r--tests/lookup/tests.py12
-rw-r--r--tests/postgres_tests/test_json.py15
3 files changed, 33 insertions, 1 deletions
diff --git a/tests/lookup/models.py b/tests/lookup/models.py
index 3f1f14dfbc..8c8cb67827 100644
--- a/tests/lookup/models.py
+++ b/tests/lookup/models.py
@@ -5,6 +5,7 @@ This demonstrates features of the database API.
"""
from django.db import models
+from django.db.models.lookups import IsNull
class Alarm(models.Model):
@@ -55,6 +56,12 @@ class NulledTransform(models.Transform):
template = 'NULL'
+@NulledTextField.register_lookup
+class IsNullWithNoneAsRHS(IsNull):
+ lookup_name = 'isnull_none_rhs'
+ can_use_none_as_rhs = True
+
+
class Season(models.Model):
year = models.PositiveSmallIntegerField()
gt = models.IntegerField(null=True, blank=True)
diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py
index eb6600bc9b..1d2a78c717 100644
--- a/tests/lookup/tests.py
+++ b/tests/lookup/tests.py
@@ -8,7 +8,9 @@ from django.db import connection
from django.db.models.functions import Substr
from django.test import TestCase, skipUnlessDBFeature
-from .models import Article, Author, Game, Player, Season, Tag
+from .models import (
+ Article, Author, Game, IsNullWithNoneAsRHS, Player, Season, Tag,
+)
class LookupTests(TestCase):
@@ -895,3 +897,11 @@ class LookupTests(TestCase):
with self.subTest(lookup=lookup):
authors = Author.objects.filter(**{'name__%s' % lookup: Substr('alias', 1, 3)})
self.assertCountEqual(authors, result)
+
+ def test_custom_lookup_none_rhs(self):
+ """Lookup.can_use_none_as_rhs=True allows None as a lookup value."""
+ season = Season.objects.create(year=2012, nulled_text_field=None)
+ query = Season.objects.get_queryset().query
+ field = query.model._meta.get_field('nulled_text_field')
+ self.assertIsInstance(query.build_lookup(['isnull_none_rhs'], field, None), IsNullWithNoneAsRHS)
+ self.assertTrue(Season.objects.filter(pk=season.pk, nulled_text_field__isnull_none_rhs=True))
diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py
index 305278fc6a..2f0b55a292 100644
--- a/tests/postgres_tests/test_json.py
+++ b/tests/postgres_tests/test_json.py
@@ -4,6 +4,7 @@ from decimal import Decimal
from django.core import checks, exceptions, serializers
from django.core.serializers.json import DjangoJSONEncoder
+from django.db.models import Q
from django.forms import CharField, Form, widgets
from django.test.utils import isolate_apps
from django.utils.html import escape
@@ -177,6 +178,20 @@ class TestQuerying(PostgreSQLTestCase):
[self.objs[7], self.objs[8]]
)
+ def test_none_key(self):
+ self.assertSequenceEqual(JSONModel.objects.filter(field__j=None), [self.objs[8]])
+
+ def test_none_key_exclude(self):
+ obj = JSONModel.objects.create(field={'j': 1})
+ self.assertSequenceEqual(JSONModel.objects.exclude(field__j=None), [obj])
+
+ def test_isnull_key_or_none(self):
+ obj = JSONModel.objects.create(field={'a': None})
+ self.assertSequenceEqual(
+ JSONModel.objects.filter(Q(field__a__isnull=True) | Q(field__a=None)),
+ self.objs[:7] + self.objs[9:] + [obj]
+ )
+
def test_contains(self):
self.assertSequenceEqual(
JSONModel.objects.filter(field__contains={'a': 'b'}),