From c7bfcd2f377ad5803e25ee547dee9cf58ee68ab2 Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Tue, 15 Nov 2016 01:47:20 +0600 Subject: [PATCH] Fixed #27481 -- Made SQLite return annotated boolean values as boolean, not integer. Thanks Simon Charette for review. --- django/db/backends/sqlite3/operations.py | 5 +++++ tests/annotations/tests.py | 14 +++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 47a26b5165..57c65a366e 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -209,6 +209,8 @@ class DatabaseOperations(BaseDatabaseOperations): converters.append(self.convert_decimalfield_value) elif internal_type == 'UUIDField': converters.append(self.convert_uuidfield_value) + elif internal_type in ('NullBooleanField', 'BooleanField'): + converters.append(self.convert_booleanfield_value) return converters def convert_datetimefield_value(self, value, expression, connection, context): @@ -242,6 +244,9 @@ class DatabaseOperations(BaseDatabaseOperations): value = uuid.UUID(value) return value + def convert_booleanfield_value(self, value, expression, connection, context): + return bool(value) if value in (1, 0) else value + def bulk_insert_sql(self, fields, placeholder_rows): return " UNION ALL ".join( "SELECT %s" % ", ".join(row) diff --git a/tests/annotations/tests.py b/tests/annotations/tests.py index 0515ac1ca1..b90286b9da 100644 --- a/tests/annotations/tests.py +++ b/tests/annotations/tests.py @@ -6,7 +6,7 @@ from decimal import Decimal from django.core.exceptions import FieldDoesNotExist, FieldError from django.db.models import ( BooleanField, CharField, Count, DateTimeField, ExpressionWrapper, F, Func, - IntegerField, Q, Sum, Value, + IntegerField, NullBooleanField, Q, Sum, Value, ) from django.db.models.functions import Lower from django.test import TestCase, skipUnlessDBFeature @@ -488,3 +488,15 @@ class NonAggregateAnnotationTestCase(TestCase): ], lambda c: (c.name, c.tagline_lower) ) + + def test_boolean_value_annotation(self): + books = Book.objects.annotate( + is_book=Value(True, output_field=BooleanField()), + is_pony=Value(False, output_field=BooleanField()), + is_none=Value(None, output_field=NullBooleanField()), + ) + self.assertGreater(len(books), 0) + for book in books: + self.assertIs(book.is_book, True) + self.assertIs(book.is_pony, False) + self.assertIsNone(book.is_none)