Loading django/db/models/expressions.py +5 −0 Original line number Diff line number Diff line Loading @@ -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] Loading tests/annotations/tests.py +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading tests/expressions/tests.py +14 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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')) Loading Loading
django/db/models/expressions.py +5 −0 Original line number Diff line number Diff line Loading @@ -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] Loading
tests/annotations/tests.py +7 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
tests/expressions/tests.py +14 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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')) Loading