diff options
| author | Dmitry Dygalo <dadygalo@gmail.com> | 2018-02-20 16:47:12 +0100 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2018-04-04 10:53:46 -0400 |
| commit | c979c0a2b8abca325a549961fd7a17bdc36bcb1f (patch) | |
| tree | b6d221918b9c0989cbb3d6dc08cd7ebee08381bf /tests | |
| parent | 4fe5d846666d46a5395a5f0ea2845a96b6837a75 (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.py | 7 | ||||
| -rw-r--r-- | tests/lookup/tests.py | 12 | ||||
| -rw-r--r-- | tests/postgres_tests/test_json.py | 15 |
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'}), |
