Fixed null handling in Value expression

This commit is contained in:
Josh Smeaton 2015-01-07 21:30:25 +11:00 committed by Tim Graham
parent 1f03d2d924
commit 8713ea7568
3 changed files with 26 additions and 1 deletions

View File

@ -483,6 +483,11 @@ class Value(ExpressionNode):
self.value = value self.value = value
def as_sql(self, compiler, connection): 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] return '%s', [self.value]

View File

@ -190,6 +190,13 @@ class NonAggregateAnnotationTestCase(TestCase):
lambda d: (d.other_name, d.other_chain, d.is_open, d.book_isbn) 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): def test_column_field_ordering(self):
""" """
Test that columns are aligned in the correct order for Test that columns are aligned in the correct order for

View File

@ -5,7 +5,7 @@ import datetime
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from django.db import connection, transaction, DatabaseError 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 import TestCase, skipIfDBFeature, skipUnlessDBFeature
from django.test.utils import Approximate from django.test.utils import Approximate
from django.utils import six from django.utils import six
@ -174,6 +174,19 @@ class BasicExpressionsTests(TestCase):
ordered=False 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): def test_filter_with_join(self):
# F Expressions can also span joins # F Expressions can also span joins
Company.objects.update(point_of_contact=F('ceo')) Company.objects.update(point_of_contact=F('ceo'))