summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/db/models/expressions.py5
-rw-r--r--tests/annotations/tests.py7
-rw-r--r--tests/expressions/tests.py15
3 files changed, 26 insertions, 1 deletions
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index ac69307edc..9fe3a35fee 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -483,6 +483,11 @@ class Value(ExpressionNode):
self.value = value
def as_sql(self, compiler, connection):
+ if self.value is None:
+ # cx_Oracle does not always convert None to the appropriate
+ # NULL type (like in case expressions using numbers), so we
+ # use a literal SQL NULL
+ return 'NULL', []
return '%s', [self.value]
diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py
index 570ef4d52c..90a9c13048 100644
--- a/tests/annotations/tests.py
+++ b/tests/annotations/tests.py
@@ -190,6 +190,13 @@ class NonAggregateAnnotationTestCase(TestCase):
lambda d: (d.other_name, d.other_chain, d.is_open, d.book_isbn)
)
+ def test_null_annotation(self):
+ """
+ Test that annotating None onto a model round-trips
+ """
+ book = Book.objects.annotate(no_value=Value(None, output_field=IntegerField())).first()
+ self.assertIsNone(book.no_value)
+
def test_column_field_ordering(self):
"""
Test that columns are aligned in the correct order for
diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py
index 0e9bd57e91..8165a496dc 100644
--- a/tests/expressions/tests.py
+++ b/tests/expressions/tests.py
@@ -5,7 +5,7 @@ import datetime
from django.core.exceptions import FieldError
from django.db import connection, transaction, DatabaseError
-from django.db.models import F
+from django.db.models import F, Value
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
from django.test.utils import Approximate
from django.utils import six
@@ -174,6 +174,19 @@ class BasicExpressionsTests(TestCase):
ordered=False
)
+ def test_update_with_none(self):
+ Number.objects.create(integer=1, float=1.0)
+ Number.objects.create(integer=2)
+ Number.objects.filter(float__isnull=False).update(float=Value(None))
+ self.assertQuerysetEqual(
+ Number.objects.all(), [
+ None,
+ None,
+ ],
+ lambda n: n.float,
+ ordered=False
+ )
+
def test_filter_with_join(self):
# F Expressions can also span joins
Company.objects.update(point_of_contact=F('ceo'))